当前位置:   article > 正文

蓝桥杯2015年第六届C/C++ B组省赛习题题解_2015年蓝桥杯c语言b组题解

2015年蓝桥杯c语言b组题解

目录

第一题:奖券数目

第二题:星系炸弹(日期计算)

第三题:三羊献瑞(全排列)

第四题:格子中输出

第五题:九数组分数(dfs)

 第六题:加法变乘法(枚举)

第七题:牌型种数(dfs+dp)

第八题:移动距离(数学+多情况+曼哈顿距离)

第九题:垒骰子(矩阵快速幂)

第十题:生命之树(dfs)


题目来源:

2015年第六届C/C++ B组蓝桥杯省赛真题_元气算法的博客-CSDN博客_2015年蓝桥杯c语言b组试题


第一题:奖券数目

  1. #include<iostream>
  2. using namespace std;
  3. bool check(int num)
  4. {
  5. while (num)
  6. {
  7. int j = num % 10;
  8. if (j == 4) return false;
  9. num /= 10;
  10. }
  11. return true;
  12. }
  13. int main()
  14. {
  15. int cnt = 0;
  16. for (int i = 10000; i <= 99999; i++)
  17. {
  18. if (check(i)) cnt++;
  19. }
  20. cout << cnt << endl;//52488
  21. return 0;
  22. }

第二题:星系炸弹(日期计算

 解析:

其实1000天也不难算,手算即可,但还是严谨的用代码给出答案

  1. #include<iostream>
  2. using namespace std;
  3. int months[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
  4. bool is_leap(int year)
  5. {
  6. return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0));
  7. }
  8. int main()
  9. {
  10. int year = 2014;
  11. int month = 11;
  12. int day = 9;
  13. int T = 1000;
  14. while (T--)
  15. {
  16. day++;
  17. if (month == 2)
  18. {
  19. if (is_leap(year)) months[2] = 29;//如果是闰年
  20. }
  21. if (day > months[month])//如果天数已经大于该月的天数时
  22. {
  23. if (month == 12)//如果该月是12月,那么就++年
  24. {
  25. year++;
  26. month = 1;//月份重新变为1
  27. day = 1;
  28. }
  29. else month++, day = 1;//否则只是月份++
  30. }
  31. months[2] = 28;//还原
  32. }
  33. printf("%d-%02d-%02d\n", year, month, day);//2017-08-05
  34. return 0;
  35. }

第三题:三羊献瑞(全排列

 解析:

由小学数学可知:

三:一定是数字1,这个不要问为什么,就是这样的,自己模拟一下

然后就是全排列找出所有的可能,然后进行对应数字之间的判断即可

  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. int main()
  5. {
  6. int num[9] = { 0,2,3,4,5,6,7,8,9 };
  7. do {
  8. if (num[0] != 0)//数字的开头不能为0
  9. {
  10. int a = num[0] * 1000 + num[1] * 100 + num[2] * 10 + num[3];
  11. int b = 1000 + num[4] * 100 + num[5] * 10 + num[1];
  12. int c = 10000 + num[4] * 1000 + num[2] * 100 + num[1] * 10 + num[6];
  13. if (a + b == c)
  14. {
  15. cout << "1" << num[4] << num[5] << num[1] << endl;
  16. break;//1085
  17. }
  18. }
  19. } while (next_permutation(num, num + 9));
  20. return 0;
  21. }

第四题:格子中输出


第五题:九数组分数(dfs)

  1. #include <stdio.h>
  2. void test(int x[])
  3. {
  4. int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
  5. int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
  6. if(a*3==b) printf("%d / %d\n", a, b);
  7. }
  8. void f(int x[], int k)
  9. {
  10. int i,t;
  11. if(k>=9){
  12. test(x);
  13. return;
  14. }
  15. for(i=k; i<9; i++){
  16. {t=x[k]; x[k]=x[i]; x[i]=t;}
  17. f(x,k+1);
  18. _____________________________________________ // 填空处
  19. }
  20. }
  21. int main()
  22. {
  23. int x[] = {1,2,3,4,5,6,7,8,9};
  24. f(x,0);
  25. return 0;
  26. }

解析:

我已经看到蓝桥杯的f函数就已经知道它是dfs了,没毛病啊兄弟们,毕竟还有个return,都知道是递归了,递归之后要还原,那么就要知道上一步是干什么,交换是吧,那么再交换一次就还原了,即可

所以答案是:{t=x[k]; x[k]=x[i]; x[i]=t;}


 第六题:加法变乘法(枚举)

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. for (int i = 1; i < 49; i ++) // 枚举第一个 * 左边的数字
  6. for (int j = i + 2; j < 49; j ++) // 枚举第二个 * 左边的数字
  7. {
  8. if(1225 - 2*i-1 - 2*j-1 + i*(i+1) + j*(j+1) == 2015)
  9. cout << i << endl;
  10. }
  11. return 0;
  12. }

第七题:牌型种数(dfs+dp)

 DFS:

  1. #include<iostream>
  2. using namespace std;
  3. int ans;
  4. void dfs(int kind, int sum)
  5. {
  6. if (sum > 13) return;
  7. if (kind == 14)
  8. {
  9. if (sum == 13) ans++;
  10. return;
  11. }
  12. for (int i = 0; i <= 4; i++)
  13. {
  14. dfs(kind + 1, sum + i);//这种类型,选多少张牌
  15. }
  16. }
  17. int main()
  18. {
  19. dfs(1, 0);
  20. cout << ans << endl;
  21. return 0;
  22. }

动态规划dp:

dp分析:

(1)dp数组的含义:dp[i][k],i:牌的种类,共13种;k:剩余需要选取多少张牌

(2)dp数组的属性:方案数

(3)dp数组的递推公式:dp[i][k]=

<1>上一类牌,选了0张,dp[i-1][k];

<2>上一类牌,选了一张,dp[i-1][k+1];

<3>上一类牌,选了两张,dp[i-1][k+2];

<3>上一类牌,选了三张,dp[i-1][k+3];

<4>上一类牌,选了四张,dp[i-1][k+4];

这样枚举有些麻烦,所以用一层for循环代替

(4)dp数组的初始化:

由递推公式可知,必须要初始化一个dp[1][一个比较大的数],那么这个比较大的数是多少呢?

对于第一类牌,可以拿0~4张,那么就有:

  1. for(int i=9; i<=13; i++){
  2. num[1][i] = 1;

需要倒过来想:

(5)dp数组的遍历顺序:

无特殊要求,两层正序即可

(6)dp数组的返回值:

根据定义从前13类牌中选,当剩余需求排数为0时,即可满足题意要求

  1. #include<iostream>
  2. using namespace std;
  3. int dp[14][14];
  4. int main()
  5. {
  6. for (int i = 9; i <= 13; i++) dp[1][i] = 1;//当剩余9~13张要选时,均初始化方案数为1
  7. for(int i=2;i<=13;i++)//枚举牌的种类
  8. for(int k=0;k<=13;k++)//枚举剩余需要选的牌的数量
  9. for (int prek = k; prek <= k + 4 && prek <= 13; prek++)//只能选1~4张该种牌
  10. {
  11. dp[i][k] += dp[i - 1][prek];//该类牌的数量=原本+上一类牌选取的四种方案数
  12. }
  13. cout << dp[13][0] << endl;
  14. return 0;
  15. }

第八题:移动距离(数学+多情况+曼哈顿距离

  1. #include <cstring>
  2. #include <iostream>
  3. #include <algorithm>
  4. using namespace std;
  5. int main()
  6. {
  7. int w, m, n;
  8. cin >> w >> m >> n;
  9. m --, n -- ;//为了对应
  10. int x1 = m / w, x2 = n / w;
  11. int y1 = m % w, y2 = n % w;
  12. if (x1 % 2) y1 = w - 1 - y1;//奇偶情况
  13. if (x2 % 2) y2 = w - 1 - y2;
  14. cout << abs(x1 - x2) + abs(y1 - y2) << endl;
  15. return 0;
  16. }

第九题:垒骰子(矩阵快速幂)

第六届蓝桥杯【省赛试题9】垒骰子 ( 矩阵快速幂 )_i逆天耗子丶的博客-CSDN博客

 AcWing 1217. 垒骰子 - AcWing


第十题:生命之树(dfs)

 

解析:

[AcWing蓝桥杯]之复杂DP(C++题解)_lihua777的博客-CSDN博客

vector模拟单链表:

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. using namespace std;
  5. typedef long long ll;
  6. const int N = 1e5 + 5;
  7. int n, w[N];
  8. ll f[N];
  9. vector<int>e[N];
  10. void dfs(int u, int fa)
  11. {
  12. f[u] = w[u];
  13. int len = e[u].size();
  14. for (int i = 0; i < len; i++)
  15. {
  16. int j = e[u][i];
  17. if (j != fa)
  18. {
  19. dfs(j, u);
  20. f[u] += max(0ll, f[j]);
  21. }
  22. }
  23. return;
  24. }
  25. int main()
  26. {
  27. cin >> n;
  28. for (int i = 1; i <= n; i++)
  29. {
  30. cin >> w[i];
  31. }
  32. for (int i = 0; i < n - 1; i++)
  33. {
  34. int x, y;
  35. cin >> x >> y;
  36. e[x].push_back(y);
  37. e[y].push_back(x);
  38. }
  39. dfs(1, -1);
  40. ll res = f[1];
  41. for (int i = 2; i < n; i++)res = max(res, f[i]);
  42. printf("%lld",res);
  43. }

数组模拟单链表:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long LL;
  6. const int N = 100010, M = N * 2;
  7. int n;
  8. int w[N];
  9. int h[N], e[M], ne[M], idx;
  10. LL f[N];
  11. void add(int a, int b)
  12. {
  13. e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
  14. }
  15. void dfs(int u, int father)
  16. {
  17. f[u] = w[u];
  18. for (int i = h[u]; i != -1; i = ne[i])
  19. {
  20. int j = e[i];
  21. if (j != father)
  22. {
  23. dfs(j, u);
  24. f[u] += max(0ll, f[j]);
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. scanf("%d", &n);
  31. memset(h, -1, sizeof h);
  32. for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);
  33. for (int i = 0; i < n - 1; i ++ )
  34. {
  35. int a, b;
  36. scanf("%d%d", &a, &b);
  37. add(a, b), add(b, a);
  38. }
  39. dfs(1, -1);
  40. LL res = f[1];
  41. for (int i = 2; i <= n; i ++ ) res = max(res, f[i]);
  42. printf("%lld\n", res);
  43. return 0;
  44. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号