当前位置:   article > 正文

2022年蓝桥杯省赛真题解析(C++B组)_蓝桥杯真题

蓝桥杯真题

        2022.04.09,我第一次参加蓝桥杯,我想说今年官方为了防止作弊,可谓煞费苦心,直接启用备用卷,难度直接到国赛难度。第一次参加,却让我输的那么彻底。


        2023.04.05更新了题解,祝各位在4.8能取得一个圆满的成绩!


目录

A九进制转十进制​

B 顺子日期

C 刷题统计

D 修剪灌木

E X进制减法

F 统计子矩阵

G 积木画 

H 扫雷

I 李白打酒加强版

J 砍竹子


A九进制转十进制

答案:1478

B 顺子日期

答案:4 / 14

解析:我填了4,当时我一直在想012算不算,题目说了20220123有一个顺子:123,没说是012,所以我认定它不算,那就只有20220123,20221123,20221230,20221231。注意:降序是不算顺子的。

C 刷题统计

for(50分吧)

  1. #include <bits/stdc++.h>
  2. #define MOD 1000000007
  3. using namespace std;
  4. typedef long long LL;
  5. LL a,b,n;
  6. int main() {
  7. int sum=0;
  8. cin>>a>>b>>n;
  9. for(LL i=1; ;i++) {
  10. if(i%7!=6 && i%7!=0) sum+=a;
  11. else sum+=b;
  12. if(sum>=n) {
  13. cout<<i;
  14. return 0;
  15. }
  16. }
  17. return 0;
  18. }

优化(应该100)

  1. #include <bits/stdc++.h>
  2. #define MOD 1000000007
  3. using namespace std;
  4. typedef long long LL;
  5. LL a,b,n;
  6. int main() {
  7. cin>>a>>b>>n;
  8. LL sum=a*5+b*2;//一周的做题数
  9. LL t=n/sum;//需要t周(往下取整)
  10. LL nn=t*sum;//t周做了nn个题目
  11. if(nn>=n) cout<<t*7;
  12. else if(nn+a>=n) cout<<t*7+1;
  13. else if(nn+a*2>=n) cout<<t*7+2;
  14. else if(nn+a*3>=n) cout<<t*7+3;
  15. else if(nn+a*4>=n) cout<<t*7+4;
  16. else if(nn+a*5>=n) cout<<t*7+5;
  17. else if(nn+a*5+b>=n) cout<<t*7+6;
  18. else if(nn+a*5+b*2>=n) cout<<t*7+7;//考试时没写这句,刚刚试数据查到错的....彻底无语,大无语事件
  19. return 0;
  20. }

D 修剪灌木

 解析:我是直接用草稿纸手推出来,发现的规律,1需要特判:1。2输出2 2,3输出4 2 4,4输出6 4 4 6,5输出8 6 4 6 8……以此类推就好了,我们看到边界是最高的,然后往中间成以公差为-2递减。所以用双指针控制它即可

  1. #include <bits/stdc++.h>
  2. #define MOD 1000000007
  3. using namespace std;
  4. typedef long long LL;
  5. int a[10005];
  6. int n;
  7. int main() {
  8. cin>>n;
  9. if(n==1) {
  10. cout<<1;
  11. return 0;
  12. }
  13. int s=(n-1)*2;
  14. int l=1,r=n;
  15. while(l<=r) {
  16. a[l]=a[r]=s;
  17. l++,r--;
  18. s-=2;
  19. }
  20. for(int i=1; i<=n; i++)
  21. cout<<a[i]<<endl;
  22. return 0;
  23. }

E X进制减法

        我在考场上看到好多人卡这题,主要是读不懂题,出考场时有很多人问我321怎么等于65,题目说了三个位的进制分别是8 10 2(从左到右),所以就是3 * 20 + 2 * 2 + 1 = 65,看不懂的小伙伴可以回去好好复习一下二进制或者往下看。

解析:

        321的“1”是2进制,逢2进1,即“2”就意味着数字4=2*2,“2”的进制是10进制,逢10进1,也就是说对于“2”来说,“3”代表着30,而对于“1”来说“3”则代表着60=30*2。通俗的说,假如321整个树是10进制,那么对于“2”而言“3”是30,对于“1”而言,“3”是300=3*10*10.

        然后,这里的最高位进制是没用的,相当于摆设。由于它说a b同一条进制系统,所以数位的进制应该是一样的,那么我们就需要一个s数组来存放当前数位应该*哪个数了

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 1e5+10, mod=1000000007;
  6. typedef long long LL;
  7. LL a[N], b[N],res;
  8. int n,ma,mb;
  9. int main()
  10. {
  11. cin>>n;
  12. cin>>ma;
  13. for(int i=ma-1; i>=0; i--) cin>>a[i];
  14. cin>>mb;
  15. for(int i=mb-1; i>=0; i--) cin>>b[i];
  16. for(int i=max(ma,mb)-1; i>=0; i--)
  17. {
  18. LL h=max(a[i]+1ll, max(b[i]+1ll, 2ll));
  19. res=(res*h%mod+(LL)(a[i]-b[i]))%mod;
  20. }
  21. cout<<res;
  22. return 0;
  23. }

F 统计子矩阵

二维前缀和,不会。。。

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long LL;
  6. const int N = 510;
  7. int s[N][N];
  8. int n,m,k;
  9. LL res;
  10. int main()
  11. {
  12. scanf("%d%d%d",&n,&m,&k);
  13. for(int i=1; i<=n; i++)
  14. for(int j=1; j<=m; j++)
  15. {
  16. scanf("%d",&s[i][j]);
  17. s[i][j]+=s[i-1][j];
  18. }
  19. for(int i=1; i<=n; i++)
  20. for(int j=i; j<=n; j++)
  21. for(int l=1,r=1,sum=0; r<=m; r++)
  22. {
  23. sum+=s[j][r]-s[i-1][r];
  24. while(sum>k)
  25. {
  26. sum-=s[j][l]-s[i-1][l];
  27. l++;
  28. }
  29. res=(LL)res+r-l+1;
  30. }
  31. cout<<res;
  32. return 0;
  33. }

G 积木画 

听他们说这道题在洛谷有原题,而且是用dp做,完全和他们不一样,我用斐波那契做的 

解析:

        这题我依旧是手推找规律。

        n为1时是1 = 1 + 0 * 2;

        n为2时是2 = 2 + 0 * 2;

        n为3时是5 = 3 + 1 * 2;

        n为4时是9 = 5 + 2 * 2;

        n为5时是18 = 8 + 5 * 2;

        n为6时是35 = 13 + 12 * 2;

        n为7时是67 = 21 + 23 * 2;以此类推

        我们发现前面的(只有I形)是斐波那契数列,后面的(有L和I型)是一个有规律的数列吧,我也不知道啥数列:2 + 3 = 5,5 + 6 = 11,11 + 12 = 23

        我也不知道对不对,没管后面了,直接编程交了,然后看了一下洛谷的,发现错了。

        代码就不给了,这个是错误思路,正解请移步洛谷P1990

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 1e7+10, mod=1000000007;
  6. typedef long long LL;
  7. LL f[N];
  8. int n;
  9. int main()
  10. {
  11. cin>>n;
  12. f[1]=1;
  13. f[2]=2;
  14. f[3]=5;
  15. for(int i=4; i<=n; i++)
  16. f[i]=(2*f[i-1]%mod+f[i-3])%mod;
  17. cout<<f[n];
  18. return 0;
  19. }

H 扫雷

 

 这个我好像用两个for,不知道能不能骗分,听一个小伙伴说是0分,那太好了,又错了.......

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long LL;
  6. const int N = 50010, M=999997;
  7. LL h[M]; //哈希值
  8. bool st[M]; //标记当前坑位是否被用过
  9. int id[M]; //坑位对应的最大半径的炸雷的编号
  10. int n,m;
  11. //存储炸雷
  12. struct circle
  13. {
  14. int x,y,r;
  15. }cir[N];
  16. //把x和y合并起来
  17. LL get_key(int x,int y)
  18. {
  19. return x*1000000001ll+y;
  20. }
  21. //找坑位
  22. int find(int x,int y)
  23. {
  24. LL key=get_key(x,y);
  25. int t=(key%M+M)%M;
  26. //空坑位或者找到目标点
  27. while(h[t]!=-1 && h[t]!=key)
  28. if(++ t==M) t=0;
  29. return t;
  30. }
  31. int sqr(int x)
  32. {
  33. return x*x;
  34. }
  35. void dfs(int x,int y,int r)
  36. {
  37. st[find(x,y)]=true;
  38. for(int i=x-r; i<=x+r; i++)
  39. for(int j=y-r; j<=y+r; j++)
  40. {
  41. if(sqr(i-x)+sqr(j-y)<=sqr(r))
  42. {
  43. int t=find(i,j);
  44. if(!st[t] && id[t])
  45. dfs(i,j,cir[id[t]].r);
  46. }
  47. }
  48. }
  49. int main()
  50. {
  51. scanf("%d%d", &n, &m);
  52. memset(h, -1, sizeof h);
  53. for(int i=1; i<=n; i++)
  54. {
  55. int x,y,r;
  56. scanf("%d%d%d",&x,&y,&r);
  57. cir[i]={x,y,r};
  58. int t=find(x,y); //找到对应的坑位
  59. if(h[t]==-1) h[t]=get_key(x,y); //坑位对应一个哈希值
  60. if(!id[t] || cir[id[t]].r < r) id[t]=i;
  61. }
  62. //遍历导弹
  63. while (m -- )
  64. {
  65. int x,y,r;
  66. scanf("%d%d%d",&x,&y,&r);
  67. for(int i=x-r; i<=x+r; i++)
  68. for(int j=y-r; j<=y+r; j++)
  69. {
  70. if(sqr(i-x)+sqr(j-y)<=sqr(r))
  71. {
  72. int t=find(i,j);
  73. //当前位置有雷且未被遍历
  74. if(!st[t] && id[t])
  75. dfs(i,j,cir[id[t]].r);
  76. }
  77. }
  78. }
  79. int res=0;
  80. for(int i=1; i<=n; i++)
  81. if(st[find(cir[i].x, cir[i].y)]) res++;
  82. cout<<res;
  83. return 0;
  84. }

I 李白打酒加强版

dfs能骗分,考的时候没想出来 

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 105, mod=1000000007;
  6. typedef long long LL;
  7. int n,m,res;
  8. LL f[N][N][N]; //店 花 酒
  9. int main()
  10. {
  11. cin>>n>>m;
  12. f[0][0][2]=1;
  13. for(int i=0; i<=n; i++)
  14. for(int j=0; j<=m; j++)
  15. for(int k=0; k<=m; k++)
  16. {
  17. if(i && k%2==0) f[i][j][k]=(f[i-1][j][k/2]+f[i][j][k])%mod;
  18. if(j && k>0) f[i][j][k]=(f[i][j-1][k+1]+f[i][j][k])%mod;
  19. }
  20. cout<<f[n][m-1][1]; //最后一次遇花留一斗
  21. return 0;
  22. }

J 砍竹子

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cmath>
  5. using namespace std;
  6. const int N = 2e5+10, M=20;
  7. typedef long long LL;
  8. LL f[N][M];
  9. int n, m, res;
  10. int main()
  11. {
  12. cin>>n;
  13. for(int i=0; i<n; i++)
  14. {
  15. int stk[M], hh=0;
  16. LL x;
  17. cin>>x;
  18. while(x>1)
  19. {
  20. stk[hh++]=x;
  21. x=sqrtl(x/2+1);
  22. res++;
  23. }
  24. m=max(m,hh);
  25. for(int j=0; j<hh; j++)
  26. f[i][j]=stk[hh-j-1];
  27. }
  28. for(int i=0; i<m; i++)
  29. for(int j=1; j<n; j++)
  30. if(f[j][i]==f[j-1][i] && f[j][i])
  31. res--;
  32. cout<<res;
  33. return 0;
  34. }

这次顶死40分,没省二咯,该退役咯~~~

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

闽ICP备14008679号