题目

  • A:颜色叠加
  • B:勤劳的老杨
  • C:秘密大厦的访客
  • D:最大能量
  • E:最大素数
  • F:最大计分
  • G:密匙
  • H:X星大学

A:颜色叠加

题目描述
热爱科学的Kimi这段时间在研究各种颜色,今天他打算做一个关于颜色叠加的小实验。
Kimi有很多张蓝色和黄色的长方形透明塑料卡片。众所周知,如果把蓝色和黄色混合在一起就会变成绿色。因此,Kimi对着光观察蓝色透明卡片和黄色透明卡片的叠加部分也就可以看到绿色啦。
假设在一个二维平面中,一张蓝色的透明卡片和一张黄色的透明卡片都与坐标轴平行放置,即卡片的横边与X轴平行,竖边与Y轴平行。
现在给出一张蓝色卡片和一张黄色卡片的左上角坐标(均为整数)以及两张卡片的长和宽(均为正整数)。
【注意:此处定义与X轴平行的那组边为长边,与Y轴平行的那组边为宽边】
请编写一个程序计算这两张卡片叠加后所形成的绿色区域的面积。
输入
单组输入。
第1行输入四个整数,分别表示蓝色长方形透明卡片的左上角坐标(X坐标和Y坐标)、长和宽。两两之间用英文空格隔开。
第2行输入四个整数,分别表示黄色长方形透明卡片的左上角坐标(X坐标和Y坐标)、长和宽。两两之间用英文空格隔开。
两张长方形透明卡片的X坐标和Y坐标的取值范围为[-1000, 1000],长和宽的取值范围为[1,200]。
输出
输出一个非负整数,表示两张卡片叠加后所形成的绿色区域的面积。
样例输入
0 100 200 100
100 150 75 75
样例输出
1875

分析:模拟题意,构造结构体变量来存储矩形的最高水平线、最低水平线,最靠左垂直线以及最靠右垂直线。根据输入就可以知道两个矩形的四个点的坐标还有相对位置。自行判断一下什么情况下面积不存在,否则就推公式,得到重合部分的宽度和高度,相乘就是面积了。
代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct Node{int u,d,l,r;
};
int fun(Node a,Node b){if(a.r<=b.l)return 0;if(a.u<=b.d||a.d>=b.u)return 0;int width=min(a.r,b.r)-max(a.l,b.l);int length=min(a.u,b.u)-max(a.d,b.d);return width*length;
}
int main(){Node a,b;int length1,width1,length2,width2;scanf("%d%d%d%d",&a.l,&a.u,&width1,&length1);a.d=a.u-length1,a.r=a.l+width1;scanf("%d%d%d%d",&b.l,&b.u,&width2,&length2);b.d=b.u-length2,b.r=b.l+width2;if(a.l<b.l)cout<<fun(a,b)<<endl;else cout<<fun(b,a)<<endl;
}

B:勤劳的老杨

题目描述
勤劳的老杨最近收到了一个任务清单,在这个清单上有N项不同的工作任务。对于每一项任务都给出了两个时间[X, Y],其中X表示任务的起始时间(任务从第X天开始,包含第X天),Y表示任务的结束时间(任务到第Y天结束,包含第Y天)。
认真的老杨对待每一项任务都是一心一意的。一旦他决定做某一项任务,在该任务没有完成之前他不会同时再做另一项任务,也就是说在任意时刻老杨手头最多只有一项任务。
假设完成每一项任务所获得的报酬都是相等的。那么,老杨应该如何来安排自己的时间才可以得到最多的报酬呢?
请你编写一个程序帮老杨计算出他最多可以完成的任务数量。保证至少能完成一项任务。
输入
单组输入。
第1行输入一个正整数N表示任务清单上任务的总数。(N<=1000)
第2行到第N行每一行包含两个正整数,分别表示每一项任务的开始时间和结束时间,两个正整数之间用空格隔开。
输出
输出老杨最多可以完成的任务数量。
样例输入
7
1 4
1 3
2 7
3 4
4 6
5 10
7 8
样例输出
3
提示
对于输入样例,最多可以完成的任务数量为3,对应[1, 3](第2项任务),[4, 6](第5项任务)和[7, 8](第7项任务)这三项任务。

分析:其实就是贪心的思想,直接对所有任务进行排序,越早完成的任务排越靠前(结束时间最早的),然后for循环遍历下去,满足node[i]的开始时间在node[i-1]的结束时间之后就可以啦。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct Node{int s,d;
}node[1005];
bool cmp(Node a,Node b){return a.d<b.d;
}
int main(){int n,num=0,t=0;scanf("%d",&n);for(int i=0;i<n;++i){scanf("%d %d",&node[i].s,&node[i].d);}sort(node,node+n,cmp);int i=0;while(i<n){if(node[i].s>t)num++,t=node[i].d;i++;}printf("%d\n",num);
}

C:秘密大厦的访客

题目描述
Kimi最近在负责一栋秘密大厦的安保工作,他的工作是记录大厦的来访者情况。
每个来访者都有一个与之对应的唯一编号,在每一条到访记录中记录了该来访者的编号。
现在Kimi需要统计每一条记录中的来访者是第几次光临秘密大厦。
输入
单组输入,每组两行。
第1行包含一个正整数n,表示记录的条数,n不超过1000;
第2行包含n个正整数,依次表示Kimi的记录中每位来访者的编号,两两之间用空格隔开。
输出
输出1行,包含n个正整数,两两之间用空格隔开,依次表示每条记录中的来访者编号是第几次出现。
样例输入
6
1 1 2 2 3 1
样例输出
1 2 1 2 1 3

分析:模拟题,可以另外开辟一个数组p,p[i]的大小就表示编号为i的来访者来的次数(开始都为1,来访一次后就+1)。下面代码直接用STL的map容器啦

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){int n,num;scanf("%d",&n);map<int,int>m;while(n--){scanf("%d",&num);m[num]++;printf("%d ",m[num]);}printf("\n");
}

D:最大能量

题目描述
一年一度的宇宙超级运动会在宇宙奥特英雄体育场隆重举行。X星人为这场运动会准备了很长时间,他大显身手的时刻终于到了!
为了保持良好的竞技状态和充沛的体能,X星人准备了N种不同的能量包。
虽然每种能量包都有无限个,但是因为同一种能量包使用太多会带来副作用,因此同样的能量包不能同时使用超过两个,也就是说最多同时可以使用两个相同的能量包。
每种能量包都有一个重量值和能量值。由于这些能量包的特殊性,必须要完整地使用一个能量包才能够发挥功效,否则将失去对应的能量值。
考虑到竞赛的公平性,竞赛组委会规定每个人赛前补充的能量包的总重量不能超过W。
现在需要你编写一个程序计算出X星人能够拥有的最大能量值是多少?

输入
单组输入。
第1行包含两个正整数N和W,其中N<=103,W<=103。
第2行到第N+1行,每一行包含两个正整数,分别表示每一种能量包的重量和能量值,两个正整数之间用空格隔开。每一种能量包的重量和能量值都是小于等于100的正整数。
输出
输出X星人能够拥有的最大能量值。
样例输入
3 12
4 20
3 10
6 20
样例输出
50

分析:其实这题是多重背包的题目。。。但是!由于自己多重背包循环没记住,比赛时推导又出了点问题。。(太爱滚动数组,没想到关键时刻直接给忘了,错了太多次了)。
不过幸好这题的k给出来最大范围为2。。。我直接把数组扩大2倍,当做01背包的板子题来做。。幸好,运气眷顾了我。
这里直接给出几大背包问题的解析和理解,可能还是需要花不少时间来琢磨的:
背包九讲

代码如下(用的是一维的思想,节省空间):

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int f[1005],c[2005],w[2005];
int main(){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;++i){scanf("%d%d",&c[i],&w[i]);c[n+i]=c[i],w[n+i]=w[i];}for(int i=1;i<=2*n;++i)for(int j=m;j>=c[i];--j)f[j]=max(f[j],f[j-c[i]]+w[i]);printf("%d\n",f[m]);
}

E:最大素数

题目描述
输入一个数字字符串,从中删除若干个(包含0个)数字后可以得到一个素数,请编写一个程序求解删除部分数字之后能够得到的最大素数。
例如,输入“1234”,删除1和4,可以得到的最大素数为23。
输入
单组输入。
输入一个数字字符串,字符串的长度不超过10。
输出
输出删除0个或者多个数字之后所能得到的最大素数。如果删除到最后也得不到素数则输出“No result.” 。
样例输入
1234
样例输出
23

分析:这题直接dfs暴力搜索就行,最好的剪枝,就是让string由长到短去暴搜,搜到这个素数就是找到了。判断素数用更快速的方法:六素数法

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll maxn=0;
bool judge(ll n){if(n==1||n==0)return false;if(n==2||n==3||n==5)return true;if(n%2==0||n%3==0)return false;for(ll i=5;i<=sqrt(n);i+=6)if(n%i==0||n%(i+2)==0)return false;return true;
}
ll turn(string s){ll num=0;for(int i=0;i<s.size();++i)num=num*10+s[i]-'0';return num;
}
void fun(string s,int x){if(!x){ll num=turn(s);if(num>maxn&&judge(num))maxn=num;return;}for(int i=0;i<s.size();++i){string s1=s;s1.erase(i,1);fun(s1,x-1);}
}
int main(){string s;cin>>s;for(int i=0;i<s.size();++i){fun(s,i);if(maxn)break;}printf("%lld\n",maxn);
}

F:最大计分

题目描述
小米和小花在玩一个删除数字的游戏。
游戏规则如下:
首先随机写下N个正整数,然后任选一个数字作为起始点,从起始点开始从左往右每次可以删除一个数字,但是必须满足下一个删除的数字要小于上一个删除的数字。每成功删除一个数字计1分。
请问对于给定的N个正整数,一局游戏过后可以得到的最大计分是多少?
输入
单组输入。
第1行输入一个正整数N表示数字的个数(N<=10^3)。
第2行输入N个正整数,两两之间用空格隔开。
输出
对于给定的N个正整数,一局游戏过后可以得到的最大计分值。
样例输入
6
3 4 3 5 2 1
样例输出
4

分析:仔细一看这个题就是求一个连续下降子序列嘛。。。可得读好题,我用的是二分的哦,这个效率快多了,就是连续上升子序列逆运用。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){int N,cnt;scanf("%d",&N);cnt=0;int* num=new int[N];int* dp=new int[N];for(int i=0;i<N;i++)scanf("%d",&num[i]);dp[cnt++]=num[0];for(int i=1;i<N;i++){if(num[i]<dp[cnt-1])dp[cnt++]=num[i];else{int l=0,r=cnt-1;while(l<r){int mid=(l+r)>>1;if(dp[mid]<=num[i])r=mid;else l=mid+1;}dp[r]=num[i];}}printf("%d\n",cnt);
}

G:密匙

题目描述
X星人又截获了Y星人的一段密文。
破解这段密文需要使用一个密钥,而这个密钥存在于一个正整数N中。
聪明的X星人终于找到了获取密钥的方法:这个正整数的最后一位是一个非零数K(K>=2),需要将正整数N切分成K个小的整数,并且要使得这K个较小整数的乘积达到最大。而所得到的最大乘积就是破解密文所需的密钥。
你能否帮X星人编写一段程序来得到密钥呢?
输入
单组输入。输入一个正整数N(N的长度小于等于15),且N的最后一位为K,K>=2。
输出
将N划分为K个整数后的最大乘积。
样例输入
2342
样例输出
966

分析:可惜在有思路的时候时间已经不够了,其实就是搜索下去,利用递归,找到回归条件(k=1时直接返回、k=2时直接递推求,还是很快的),其它时候,要在for循环时就避免一些不必要的递归步骤。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll turn(string s){ll num=0;for(int i=0;i<s.size();++i)num=num*10+s[i]-'0';return num;
}
ll fun(string s,int k){if(k==1)return turn(s);if(k==2){ll res=1;for(int i=0;i<s.size();++i){string s1=s.substr(0,i+1),s2=s.substr(i+1,s.size()-i-1);ll num=turn(s1)*turn(s2);if(num>res)res=num;}return res;}ll res,maxn=1;for(int i=0;i<s.size();++i){string s1=s.substr(0,i+1),s2=s.substr(i+1,s.size()-i-1);//cout<<s1<<" "<<s2<<endl;for(int i=1;i<k;++i){if(s1.size()>=i&&s2.size()>=k-i){res=fun(s1,i)*fun(s2,k-i);//cout<<res<<endl;if(res>maxn)maxn=res;}}}return maxn;
}
int main(){string s;cin>>s;int k=s[s.size()-1]-'0';printf("%lld\n",fun(s,k));
}

H:X星大学

题目描述
X星大学新校区终于建成啦!
新校区一共有N栋教学楼和办公楼。现在需要用光纤把这N栋连接起来,保证任意两栋楼之间都有一条有线网络通讯链路。
已知任意两栋楼之间的直线距离(单位:千米)。为了降低成本,要求两栋楼之间都用直线光纤连接。
光纤的单位成本C已知(单位:X星币/千米),请问最少需要多少X星币才能保证任意两栋楼之间都有光纤直接或者间接相连?
注意:如果1号楼和2号楼相连,2号楼和3号楼相连,则1号楼和3号楼间接相连。
输入
单组输入。
第1行输入两个正整数N和C,分别表示楼栋的数量和光纤的单位成本(单位:X星币/千米),N<=100,C<=100。两者之间用英文空格隔开。
接下来N*(N-1)/2行,每行包含三个正整数,第1个正整数和第2个正整数表示楼栋的编号(从1开始一直到N),编号小的在前,编号大的在后,第3个正整数为两栋楼之间的直线距离(单位:千米)。
输出
输出最少需要多少X星币才能保证任意两栋楼之间都有光纤直接或者间接相连。
样例输入
3 10
1 2 5
1 3 6
2 3 7
样例输出
110

分析:最小生成树的板子题,最近刚复习就用到了,运气不错

有关最小生成树的讲解,可以看这篇文章:
最小生成树

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int NUM=105;
int S[NUM];
struct Edge{int u,v,w;}edge[NUM*NUM];
bool cmp(Edge a,Edge b){return a.w<b.w;
}
int find(int u){return S[u]==u?u:find(S[u]);
}
int n,m;
int kruskal(){int ans=0;for(int i=1;i<=n;++i)S[i]=i;sort(edge+1,edge+m+1,cmp);for(int i=1;i<=m;++i){int b=find(edge[i].u);int c=find(edge[i].v);if(b==c)continue;S[c]=b;ans+=edge[i].w;}return ans;
}
int main(){int c;scanf("%d%d",&n,&c);m=n*(n-1)/2;for(int i=1;i<=m;++i)scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);printf("%d\n",kruskal()*c);
}

总结
搜索题还是做的不够多,支支吾吾地写代码,还需要多练。下一次运气要是不行,我恐怕就不行了。除了多做搜索专题,还需要把背包问题。。。敲熟。。

HNUCM天梯赛选拔赛第一场相关推荐

  1. 浙江农林大学第十九届程序设计竞赛暨天梯赛选拔赛-D 涛涛和策策的游戏(尼姆博弈)

    浙江农林大学第十九届程序设计竞赛暨天梯赛选拔赛-D 涛涛和策策的游戏 链接:https://ac.nowcoder.com/acm/contest/7872/D 来源:牛客网 题目描述 涛涛和策策打码 ...

  2. c语言作业i love gplt,集思广益 | 寒假天梯赛准备第一阶段总结

    原标题:集思广益 | 寒假天梯赛准备第一阶段总结 冬季虽寒,但认真好学的信科学子,却正在耐心的为即将到来的团体程序设计天梯赛做准备,让我们一起看看天梯赛寒假备赛第一阶段大家的讨论成果吧! 讨论题目 1 ...

  3. 2020ICPC·小米 网络选拔赛第一场 J.Matrix Subtraction

    2020ICPC 小米 网络选拔赛第一场 J.Matrix Subtraction 题目链接 题目描述 Given a matrix MM_{}M​ of size n×mn\times mn×m a ...

  4. 2020ICPC·小米 网络选拔赛第一场 D.Router Mesh

    2020ICPC·小米 网络选拔赛第一场 D.Router Mesh 题目链接 题目描述 In a Mesh networking system, there are nn_{}n​ MI Route ...

  5. SWPU 2021年团队程序设计天梯赛选拔赛 题解

    补题场链接:https://pintia.cn/problem-sets/1373141720280027136 本次选拔赛除后三题以外,其余的题目难度都不是很大,简单筛选一下大家的基础.请大家这段时 ...

  6. 2022年天梯赛选拔赛第2场

    A.Kimi的心情 签到题 直接模拟,相信大家都会 #include <bits/stdc++.h> using namespace std; int n,d; int ans; int ...

  7. HNUCM2022年天梯赛选拔赛第1场

    A: 颜色叠加 题目描述 热爱科学的Kimi这段时间在研究各种颜色,今天他打算做一个关于颜色叠加的小实验. Kimi有很多张蓝色和黄色的长方形透明塑料卡片.众所周知,如果把蓝色和黄色混合在一起就会变成 ...

  8. 2021年初ICPC 天梯赛选拔赛第五场

    A. 序列 思路:前缀和,对于每个每个区间(Li,Ri,Ci),那么sum[Li1]+Ci>=sum[Ri],然后把每个这样的区间看作一条边,建图,用差分约束的思想跑SPFA,答案即为最小的数 ...

  9. 训练日记 | 2021.03.21 | 天梯赛选拔赛

    选拔赛用的是 第十八届浙大城院程设竞赛 A - Genshin and KFC 直接输出 B - Codeforces 题意:判断段位有没有改变,如果有就输出"(原段位 to 现段位)&qu ...

最新文章

  1. Android设置多个定时器时只有最后一个定时器有效的问题
  2. STL - 容器 - Set
  3. idea14创建java项目_使用IntelliJ IDEA 14和Maven创建java web项目
  4. Golang 库学习笔记 Gin(二)
  5. VTK:图像理想高通用法实战
  6. halcon求取区域顶点
  7. centos7安装Cloudera Manager
  8. java heroku_Heroku和Java –从新手到初学者,第1部分
  9. php 静态方法特点,浅析php静态方法与非静态方法的用法区别
  10. js声明变量三种方式
  11. Java多线程共享变量控制
  12. android系统app打开蓝牙+设置可见性
  13. 服务中没有listen_Odoo 中的 IM(即时通讯)实现分析
  14. 多个Tomcat同时运行环境配置 - imsoft.cnblogs
  15. [转].net中Cache的应用
  16. 【模板】堆优化 + dij +pair 存储
  17. 北京二手房上周成交环比增六成 个别业主涨价出售
  18. html白色背景遮罩,CSS 给图片或背景图片加颜色遮罩
  19. JAVA基础之单例模式
  20. Scroller的用法

热门文章

  1. aircrack-ng暴力破解WIFI密码
  2. 散户实现自动化实盘量化交易主要方式有哪些?
  3. 燕十八老师高级JS之arguments详解
  4. STO大爆发是通证经济学的福音还是区块链的末日?
  5. MATLAB代码:基于混合整数规划的微网储能电池容量规划 关键词:储能配置 电池容量规划 微网 混合整数规划
  6. 003、torchserve 调用LSTM模型预测
  7. JVM频繁GC内存溢出排查
  8. 新手初学者怎样才能学好Java?
  9. 产品健康度模型(2) KPI、KQI
  10. 新思路|保姆式智能化安防方案,开启全新商业管理模式