2022新生训练赛第四场(upc)c++
看的师哥的题解才懂这几道题的,很详细明白:https://blog.csdn.net/qq_62899367/article/details/127706848?spm=1001.2014.3001.5502
问题 D: 计时器
时间限制: 1.000 Sec 内存限制: 128 MB
题目描述
运动场修好后,体艺节马上要开始了。体艺节上要用N个计时器,每个计时器是一个中间显示秒数的方形电子表。如下图是显示5秒和201秒的两个计时器:
为了检查这些计时器的质量,晨晨创新地开发设计出一个新游戏,鼓动了M个同学报名参加。游戏开始时她把这N个计时器排成一行,开始时间都是0。然后她对这M个同学每个人发一条命令:
把第si个到第ti个计时器上时间都加1秒。
M个同学完成指令后,N个计时器上时间几乎都变了。晨晨要通过编计算机程序来计算所有计时器上的数字长度(位数)总和。例如下面N=3个计时器的数字长度分别是1、3、2,长度和是6(=1+3+2)。
输入
第1行:2个正整数N和M。(N,M均为大于0小于200000的整数)
下面有M行:每行2个整数s和t。(0<s<t<=N)
输出
一整数,表示N个数总位数长度。
样例输入 Copy
5 10
1 3
2 4
2 3
1 3
1 4
1 4
1 4
2 4
2 4
2 4
样例输出 Copy
7
提示
最后计时器上的数字分别是:5、10、10、7、0
数字长度:1+2+2+1+1=7
思路:
这道题思路挺简单,但当时做的时候还没听说过前缀和这个东西,时间总是超限,会了之后看这道题还是挺容易的
代码:
#include <bits/stdc++.h>
using namespace std;
int a[200005],d[200005];
int main(){
int i;
int n,m;
cin>>n>>m;
int x,y;
for (i=0;i<m;i++){
cin>>x>>y;
d[x]++; //构建差分数组
d[y+1]--;
}
for (i=0;i<n;i++){
a[i]=a[i-1]+d[i];//求前缀和
}
int s=0;
for (i=0;i<n;i++){
do {
a[i]=a[i]/10; //先do再while判断,因为0也算一个数字长度
s++;
}while(a[i]>0);
}
cout<<s;
}
问题 H: 朋友圈
题目描述
多多很喜欢发朋友圈,至今他已经发了N条朋友圈,并且他的第i条朋友圈获得了ci次点赞。多多听说有一个h指数来衡量朋友圈的质量,h指数是指有至少h条获得了不少于h次点赞的朋友圈的最大整数h。例如,有4条朋友圈获得的点赞次数为 (1,100,2,3),则h指数为2,如果点赞次数为 (1,100,3,3),则h指数为3。
多多想知道自己的h指数是多少。
输入
第一行为一个整数N(1<=N<=100000)。
第二行为N个整数,第i个数表示第i条朋友圈获得的点赞次数ci(0<=ci<=100000)。
输出
输出一个整数,表示多多的h指数。
样例输入 Copy
4
1 100 2 3
样例输出 Copy
2
浅说:
这道题我开始一直没读懂题目,再之一直往从小到大排去了,没有思路。
思路:
本题突破点在h指数的定义(h指数是指有至少h条获得了不少于h次点赞的朋友圈的最大整数h),那如果正好逆序排的话,到当前条的n次点赞小于小于条数m,那就说明前面的都符合要求,最大整数即为n-1;
代码:
#include <bits/stdc++.h>
using namespace std;
int a[100005];
bool cmp(int x,int y){
return x>y;
}
int main(){
int n;
cin>>n;
int i;
int flag=1;
for (i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1,cmp); //快排倒序
for (i=1;i<=n;i++){
if (i>a[i]){
cout<<i-1;
flag=0; //避免出现全部符合要求,没输出的情况
break;
}
}
if(flag==1){
cout<<n;
}
}
问题 J: 平方因子
题目描述
多多有一些正整数n,n+1,n+2,…m,如 n=3,m=9 时,多多有3,4,5,6,7,8,9 七个数。
多多不喜欢平方因子,如 4,9,16,25 都是平方因子,而1不算平方因子,多多想知道他的这些数当中有多少数中不包含平方因子?在 3~9 这些数中包含平方因子的数有4,8,9 三个数,不包含平方因子的数是 3,5,6,7 四个数。
输入
输入一行,两个数n,m(1<=n,m<=1000000)
输出
输出一个整数表示答案。
样例输入 Copy
1 10
样例输出 Copy
7
浅说:
这种对时间复杂度优化的确实伤脑筋,遇到就得坐牢。
思路:
首先确定一个i的外层循环,确保有ii的平方因子,再找另一个因子j内部循环,但要确保jii在n和m的范围,对ji*i进行标记,即为有平方因子的数。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int s[N];
int main(){
int n,m;
cin>>n>>m;
int i,j;
for (i=2;i*i<=m;i++){ //用i*i表示平方因子
for (j=n/(i*i);j*i*i<=m;j++){//j表示另一个因子
s[j*i*i]=1; //j*i*i确保在n~m的范围里
}
}
int cnt=0;
for (i=1;i<=m;i++){
if (s[i]==0){
cnt++;
}
}
cout<<cnt;
}