0


C++牛客周赛43题目分享(3)小红平分糖果,小红的完全平方数,小苯的字符串变化,小红的子数组排列判断

1.前言

哈喽大家好啊,就在刚刚的周日,结束了牛客周赛 Round 43,今天继续为大家分享一些题解,希望对大家有所帮助,也请大家多多支持我哦~

2.四道题目

2.1小红平分糖果

2.1.1题目描述

2.1.2输入描述

2.1.3输出描述

2.1.4示例

2.1.5代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. using namespace std;
  5. int main(){
  6. int n=0;
  7. scanf("%d",&n);
  8. if(n%2==0)printf("%d %d",n/2,n/2);
  9. else printf("-1");
  10. return 0;
  11. }

第一道题就是一道简单的签到题,认真审题就没有问题~

2.2小红的完全平方数

2.1.1题目描述

2.1.2输入描述

2.1.3输出描述

2.1.4示例

2.1.5代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. void func()
  7. {
  8. long long x;
  9. cin>>x;
  10. long long l=sqrt(x);
  11. long long r=l+1;
  12. if((x-l*l)%2==0)cout<<(x-l*l)/2;
  13. else cout<<(r*r-x)/2;
  14. }
  15. int main()
  16. {
  17. func();
  18. return 0;
  19. }

第二道题考了一道有关完全平方数的问题:

在解决这道题之前,我们需要先明白完全平方数的一个性质,每一个完全平方数都是由连续的自然数平方得出,由于自然数的顺序是奇数偶数交错,且奇数乘以奇数仍未奇数,偶数乘以偶数仍未偶数,因此,每一个完全平方数也是奇数偶数相交错


在知晓这一个性质之后就可以开始敲代码了,先寻找输入的这个数在哪俩个相邻的完全平方数之间,然后寻找该数离哪一个完全平方数的距离是偶数,最后输出即可。

以上代码中是直接打印出了模拟出来的结果,可以先自己在演草本上写写。

2.3小苯的字符串变化

2.1.1题目描述

2.1.2输入描述

2.1.3输出描述

2.1.4示例

2.1.5代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. const int N=100005;
  7. char s[N];
  8. int a[N],b[N];
  9. int m=0,locate=0,ans=1e9;
  10. int main(){
  11. scanf("%s",s);
  12. m=strlen(s);
  13. if(s[0]>='a'&&s[0]<='z')a[0]=1;
  14. for(int i=1;i<m;i++){
  15. if(s[i]>='a'&&s[i]<='z'){
  16. a[i]=a[i-1]+1;
  17. }
  18. else a[i]=a[i-1];
  19. }
  20. for(int j=m-1;j>=0;j--){
  21. if(s[j]>='A'&&s[j]<='Z'){
  22. b[j]=b[j+1]+1;
  23. }
  24. else b[j]=b[j+1];
  25. }
  26. for(int n=0;n<m-1;n++){
  27. ans=min(ans,a[n]+b[n+1]);
  28. }
  29. cout<<ans<<endl;
  30. return 0;
  31. }

这一道题有一点前缀和的感觉,接下来是题目思路:

根据题意,任何一个位置都可以作为那一个“分界点”,即前面小写字母(包括本分界点)都变成大写字母,后面的大写字母(不包括本分界点)都变成小写字母。因此根据这个逻辑,我们可以将每一个字母都作为“分界点”并利用循环分别计算前后大小写字母个数。


先按照题意输入,然后先进行第一个字母的判断(因为循环处可能会出现越界,所以将边界点拿出来单独处理),接着俩个循环(一个正向,一个反向)分别计算字母数量,最后再利用一个循环取所有分界点中,俩个字母数目相加的最小值,最后输出即可。

2.4小红的子数组排列判断

2.1.1题目描述

2.1.2输入描述

2.1.3输出描述

2.1.4示例

2.1.5代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. using namespace std;
  5. int n=0,k=0;//数组大小与连续子数组大小
  6. int a[100005];//存储定义排列
  7. int b[100005];//存储当下数字状态
  8. int num=0;//存储当下k数组中有多少不同的数字
  9. int ans=0;//记录答案
  10. int main(){
  11. scanf("%d%d",&n,&k);
  12. for(int i=0;i<n;i++)scanf("%d",&a[i]);
  13. for(int i=0;i<k;i++){
  14. b[a[i]]++;
  15. if(b[a[i]]==1)num++;
  16. }
  17. if(num==k)ans++;//判断前k个是否满足题意
  18. for(int i=k;i<n;i++){
  19. b[a[i-k]]--;
  20. if(b[a[i-k]]==0)num--;
  21. b[a[i]]++;
  22. if(b[a[i]]==1)num++;
  23. if(num==k)ans++;
  24. }
  25. cout<<ans<<endl;
  26. return 0;
  27. }

这道题当时拿到手里的时候,感觉题目很清晰但自己唯一能想到的方法就是暴力(就是一直不断利用for循环),但我也知道这样也会爆TLE,所以接下来给大家分享一个比较良好的算法整体思路如下:


先来为大家讲解一下题意:

我这里输入的数组与k值分别为:

数组:3 2 3 1 2 3 2 1 2 3 1 3

k值:3

我们从第一个开始往后模拟(每次往后递推一位):

3 2 3不满足。2 3 1满足。3 1 2满足。1 2 3满足。2 3 2不满足。

3 2 1满足。2 1 2不满足。1 2 3满足。2 3 1满足。3 1 3不满足。

综上所述,输出结果应为6。


从以上的模拟我们应该能发现规律,每次往后地推一位只是少了第一个数多了最后一个数,在判断该子序列是否满足题意时也大可不必采用for循环大法,可以通过判断每位数出现的次数,如果出现的次数num刚好等于k,那么ans++;相反如果子序列中有重复的数,num<k,那么ans不做处理,最后输出即可。


(还有一点也需要提到的是,如果输入的数中有大于k的数字,应当continue,但对该题无影响,这样操作更加严谨)

3.小结

今天的这四道题虽然题目较为简单,但对平时解题时思路的拓展仍有借鉴意义,看完了不要忘了点个赞喔。感谢大家的支持~


本文转载自: https://blog.csdn.net/2301_81073317/article/details/139046763
版权归原作者 爱吃烤鸡翅的酸菜鱼 所有, 如有侵权,请联系我们删除。

“C++牛客周赛43题目分享(3)小红平分糖果,小红的完全平方数,小苯的字符串变化,小红的子数组排列判断”的评论:

还没有评论