当前位置:   article > 正文

2024年第十五届蓝桥杯C/C++C组题目全解首发(AK)_蓝桥杯题目

蓝桥杯题目

五一假期,记vp一场c++c组的题目..

A: 拼正方形(结果填空)

题意:给a个2*2的方格,b个1*1的方格,问能凑成的最大正方形边长;

思路:4a+1b开根号就是答案,前提是b得是偶数且是四的倍数,不妨先将b个1*1的方格凑成2*2的,然后2*2的格子数*4后开方,就是答案;

答案:5435122


B: 劲舞团(结果填空)

题意:给2000行记录,求最长连续匹配数,匹配是指:当前记录中 第一二个字符一样 且和上一条记录(同匹配)之间的时间戳差值小于1s;

思路:

答案:9


C: 数字诗意

题意:给一个数列,问数列中有多少个数是属于一个前n项和的结果(n>=2)。

思路:数据范围显然不可能是枚举a_in,很可能需要位运算,如图,打表找规律,发现只有2的整数次幂才不满足,2的54次方刚好大于了|ai|的数据范围1e16, 所以只需要对枚举54位,数列中恰好等于k次方的数的个数就是答案。

复杂度:O(N)

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cmath>
  4. using namespace std;
  5. typedef long long ll;
  6. int main(){
  7. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  8. int m,res = 0; cin >> m;
  9. for (int i = 1; i <= m; i ++){
  10. ll x; cin >> x;
  11. for (int j = 0; j <= 54; j ++){
  12. if (x == pow(2,j)) res ++;
  13. }
  14. }
  15. cout << res <<"\n";
  16. return 0;
  17. }

D: 封闭图形个数

题意:给10以内数字加一个基础属性,0,4,6,9数字属性值是1,8的属性值是2,1,2,3,5,7的属性值是0,现给一个数列,要求按照属性值大小排序,若属性值大小相同,则输出数字本身大小

思路:结构体基础知识,重构小于号(手写sort的cmp也可以),直接把一个数字按数位拆出来然后叠加属性值就可以了,最后将数列按从小到大顺序输出。

复杂度:O(N)

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. int n;
  6. const int N = 2e5+10;
  7. struct Nod{
  8. int w;
  9. bool operator < (const Nod &k) {
  10. int r1=0,r2=0;
  11. int m1 = w, m2 = k.w;
  12. while (m1){
  13. int x = m1%10;
  14. r1+=((x==0)||(x==4)||(x==6)||(x==9));
  15. r1+=((x==8)*2);
  16. m1/=10;
  17. }
  18. while (m2){
  19. int x = m2%10;
  20. r2+=((x==0)||(x==4)||(x==6)||(x==9));
  21. r2+=((x==8)*2);
  22. m2/=10;
  23. }
  24. if (r1==r2) return w < k.w;
  25. return r1 < r2;
  26. }
  27. }arr[N];
  28. int main(){
  29. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  30. cin >> n;
  31. for (int i = 1; i <= n; i ++) cin >> arr[i].w;
  32. sort(arr+1, arr+n+1);
  33. for (int i = 1; i <= n; i ++) cout << arr[i].w << " ";
  34. return 0;
  35. }

E:回文数组

题意:给一个数列,有两个操作,一是将单个数字+1或-1,二是将相邻的两个数字同时+1或者-1,问最后将其修改为回文数列的最小修改次数。

思路:回文相关的问题一般都具有对称性,考虑第i个数和考虑第n-i+1个数问题一样,可以忽略后者,因此这里只需要处理前一半。贪心,假设现在处理的第j个数与第n-j+1个数的差值 和 即将处理的第j+1个数与第n-(j+1)+1个数的差值同号,那么就可以用操作二一次性处理,剩下的就只能是操作1了。

复杂度:O(N)

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. typedef long long ll;
  6. const int N = 2e5+10;
  7. ll a[N],p[N];
  8. ll res = 0;
  9. int main(){
  10. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  11. int n; cin >> n;
  12. for (int i = 1; i <= n; i ++) cin >> a[i];
  13. for (int i = 1, j = n; i < j; i ++, j --) p[i] = a[j] - a[i];
  14. for (int i = 1; i <= n/2; i ++){
  15. res += abs(p[i]); // 异号单独加
  16. if (p[i]>0 && p[i+1]>0) p[i+1]-=min(p[i],p[i + 1]); // 同号一起处理
  17. if (p[i]<0 && p[i+1]<0) p[i+1]-=max(p[i],p[i + 1]);
  18. }
  19. cout << res << "\n";
  20. return 0;
  21. }

F: 商品库存管理

题意:给一个全0数列,有m次操作,每次给数列中一段区间+1,求分别撤销第i次操作后,数列中0的个数。

思路:差分+前缀和。先差分所有操作,然后记录一下当前数列当中0的个数r0,因为差分后是0的数,无论撤销哪一次操作,都不会变。随后,结合题意,假定撤销某次区间[l,r]操作之后aj=0(l<=j<=r),那么也就意味着a_j在这个区间操作被撤销之前必定是1,显然,问题可以转化为:求m个区间当中1的个数。将差分后的数组中的1拎出来做前缀和,然后分别算每个操作区间当中1的个数就可以了,记得每次都要加上r0。

复杂度:O(M+N)

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. int n,m;
  6. const int N = 300010;
  7. typedef pair<int,int> PII;
  8. PII ts[N];
  9. int bs[N],pre[N];
  10. int ret = 0;
  11. int main(){
  12. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  13. cin >> n >> m;
  14. for (int i = 1; i <= m; i ++){
  15. cin >> ts[i].first >> ts[i].second;
  16. bs[ts[i].first]++,bs[ts[i].second+1]--;
  17. }
  18. for (int i =1;i<=n;i++) bs[i]+=bs[i-1], ret += (bs[i]==0);
  19. for (int i =1;i<=n;i++) pre[i]+=pre[i-1]+(bs[i]==1);
  20. for (int i = 1; i <= m; i ++){
  21. int l = ts[i].first, r = ts[i].second;
  22. cout << pre[r]-pre[l-1]+ret <<"\n";
  23. }
  24. return 0;
  25. }

G: 挖矿

题意:在一维数轴上,给若干个指定坐标x和m,从起始点出发,每次可以朝左边/右边走一个单位,问不超过距离m最多能走到多少个不同的指定坐标。

思路:先预处理一个往左右两边走分别能包含坐标数的前缀和,g[0][i]表示从起始点往左走i个单位长度能包含多少个指定坐标,g[1][i]表示从起始点往右走i个单位长度能包含多少个指定坐标。

        接着分析,假设有x_3>x_2>x_1>0(小于0的情况也一样,对称的),若x_2能被包含到答案里面,那么一定是从x_1走过来,而不可能从x_3走过来,这里也不难证明,假设从x_3x_2的路线是优的,那从起始点出发到x_3是优的、从起始点到x_2也是优的,显然与前一命题产生矛盾,所以每一个指定坐标只需要考虑是否能从比自己小的坐标走过来。

        其次讨论不同情况:情况1:从起始点一直往左走能找到解,答案就是g[0][m];情况2是情况1的镜像,答案是g[1][m]; 情况3:从起始点往左走i个单位,然后往回到起点再往右走(m-2*i>0)个单位;情况4也是情况3的镜像。

        可以发现,情况1、2其实是可以和3、4合并的(情况3、4枚举往左/右走的单位长度,当单位长度是m的时候其实就是情况1和2,能往反方向走当且仅当m-2*i>0)。

复杂度:O(N)

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. int n,m;
  5. const int N = 1e5+10, M = 2e6 + 10;
  6. typedef long long ll;
  7. ll g[2][M];
  8. int main(){
  9. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  10. cin >> n >> m;
  11. for (int i = 1; i <= n; i ++){
  12. int x;cin>>x;
  13. if (x<0) g[0][-x]=1;
  14. if (x>=0) g[1][x]=1;
  15. }
  16. // 前缀和 往左右走i步有多少个宝石
  17. for (int i = 1; i <= m; i ++) {
  18. g[0][i]+=g[0][i-1];
  19. g[1][i]+=g[1][i-1];
  20. }
  21. ll Lres = 0;
  22. for (int i = 1; i <= m; i ++){
  23. ll dis = g[0][i];
  24. if (m-2*i>0) dis += g[1][m - 2*i];
  25. Lres = max(Lres,dis);
  26. }
  27. ll Rres = 0;
  28. for (int i = 1; i <= m; i ++){
  29. ll dis = g[1][i];
  30. if (m-2*i>0) dis += g[0][m - 2*i];
  31. Rres = max(Rres,dis);
  32. }
  33. cout << max(Lres,Rres) << "\n";
  34. return 0;
  35. }

H: 回文字符串

题意:给一个字符串,可以在开头处加入任意数目个指定字符l/q/b,问能否将字符串转化为一个回文字符串。

思路:基础题实锤。既然能在字符串前面加入任意数目个l/q/b,那字符串最后面的l/q/b完全可以忽略,因为一定可以配对,问题转化为:删掉给定字符串最后面的l/q/b字符,问剩下的字符是否是回文串,评测一共是10组数据,一组字符串长度最大是1e6,也就是1e7的复杂度,On可以随便写,同时从两边遍历中间,发现对应不上就直接停止。

复杂度:O(N)

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. void solve(){
  5. string s; cin >> s;
  6. int pos = s.length()-1;
  7. for (; pos; pos --){
  8. if (s[pos]!='l' && s[pos] !='q' && s[pos]!='b') break;
  9. }
  10. string tmp = s.substr(0, pos+1); // 去掉后面那一串前面可以任意堆叠的
  11. bool fg = true;
  12. for (int i = 0,j = tmp.length()-1; i <= j; i ++, j --){ // 看看剩下的是不是回文串就可以了 复杂度On 1E7数据1秒随便跑
  13. if (tmp[i] != tmp[j]){
  14. fg = false;
  15. break;
  16. }
  17. }
  18. cout << (fg ? "Yes" : "No") << "\n";
  19. }
  20. int main(){
  21. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  22. int t; cin >> t;
  23. while (t--){
  24. solve();
  25. }
  26. return 0;
  27. }

Finally:测评成绩

以上仅为oj平台的测评结果( 评测OJ:首页 - DashOJ),若有最优解或者Hack数据欢迎在评论区讨论;

最后的最后,祝大家五一假期快乐!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/705642
推荐阅读
相关标签
  

闽ICP备14008679号