2017年蓝桥杯第八届C&C++大学B组真题及代码

打印 上一主题 下一主题

主题 958|帖子 958|积分 2874

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
1A:购物单(填空5分)
2B:等差素数列(填空7分)(枚举)
3C:承压计算(填空13分)
4D:方格分割(填空17分)(dp)
5E:取数位(代码填空9分)
6F:递增三元组(编程题11分)(前缀和)
剖析代码
7G:螺旋折线(编程题19分)
剖析代码
8H:日志统计(编程题21分)
剖析代码(过78%数据)
9I:举世变暖(编程题23分
剖析代码
10J:乘积最大(编程题25分)
剖析代码


1A:购物单(填空5分)


.................答案:5200

2B:等差素数列(填空7分)(枚举)


答案:210
  1. #include<iostream>
  2. using namespace std;
  3. long long int prime[100019];
  4. bool  isprime(long long int n)
  5. {
  6.         for (long long int i = 2; i * i <= n; i++)
  7.         {
  8.                 if (n % i == 0)
  9.                         return false;
  10.         }
  11.         return true;
  12. }
  13. int main()
  14. {
  15.         for (long long int i = 2; i <= 100009; i++)       //素数打表
  16.         {
  17.                 if (isprime(i))
  18.                         prime[i] = 1;
  19.         }
  20.         for (int i = 1; i <= 1000; i++) // 枚举公差
  21.         {
  22.                 for (int j = 1; j <= 8000; j++) // 枚举首项
  23.                 {
  24.                         int flag = 0;
  25.                         for (int k = 1; k <= 9; k++)
  26.                         {
  27.                                 if (prime[j + k * i] == 0)
  28.                                 {
  29.                                         flag = 1;
  30.                                         break;
  31.                                 }
  32.                         }
  33.                         if (!flag)
  34.                         {
  35.                                 printf("%d\n", i);
  36.                                 return 0;
  37.                         }
  38.                 }
  39.         }
  40.         return 0;
  41. }
  42. // 答案210
复制代码

3C:承压计算(填空13分)


  1.                              7
  2.                             5 8
  3.                            7 8 8
  4.                           9 2 7 2
  5.                          8 1 4 9 1
  6.                         8 1 8 8 4 1
  7.                        7 9 6 1 4 5 4
  8.                       5 6 5 5 6 9 5 6
  9.                      5 5 4 7 9 3 5 5 1
  10.                     7 5 7 9 7 4 7 3 3 1
  11.                    4 6 4 5 5 8 8 3 2 4 3
  12.                   1 1 3 3 1 6 6 5 5 4 4 2
  13.                  9 9 9 2 1 9 1 9 2 9 5 7 9
  14.                 4 3 3 7 7 9 3 6 1 3 8 8 3 7
  15.                3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
  16.               8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
  17.              8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
  18.             2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
  19.            7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
  20.           9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
  21.          5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
  22.         6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
  23.        2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
  24.       7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
  25.      1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
  26.     2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
  27.    7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
  28.   7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
  29. 5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
  30. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
复制代码


        为什么要求最小值?因为单元的不同,因此无法正确的数字,好比7无法正常从推出5 和 8,所以我们要求出单元
        单元的求法就是:题目给出了最小值,所以我们也要计算出我们得出的最小值,如许就可以得到了单元,再用这个单元去乘以最大值,就得到了题目标正确所求最大值
  1. #include <cstdio>
  2. #include <iostream>
  3. using namespace std;
  4. double g[40][40];
  5. int main()
  6. {
  7.         for (int i = 1; i <= 30; i++)
  8.                 for (int j = 1; j <= i; j++)
  9.                         cin >> g[i][j];
  10.         for (int i = 1; i <= 29; i++)
  11.         {
  12.                 for (int j = 1; j <= i; j++)
  13.                 {
  14.                         g[i + 1][j] += g[i][j] / 2;
  15.                         g[i + 1][j + 1] += g[i][j] / 2;
  16.                 }
  17.         }
  18.         double maxv = 0, minv = 0x3f3f3f3f;
  19.         for (int i = 1; i <= 30; i++)
  20.         {
  21.                 maxv = max(maxv, g[30][i]);
  22.                 minv = min(minv, g[30][i]);
  23.         }
  24.         printf("%f", 2086458231 / minv * maxv);
  25.         return 0;
  26. }
  27. // 答案72665192664
复制代码
答案72665192664

4D:方格分割(填空17分)(dp)



答案:19
  1. #include <iostream>
  2. using namespace std;
  3. #define endl '\n'
  4. #define int long long
  5. int dp[1010][5];
  6. // 状态表示:[[i][j]为i层j个手机的最多(最优)测试次数
  7. signed main()
  8. {
  9.         ios::sync_with_stdio(0);
  10.         cin.tie(0);
  11.         cout.tie(0);
  12.         for (int i = 1;i <= 1000;i++) // 边界初始化
  13.         {
  14.                 dp[i][1] = i; // 如果只有一个手机,则n层最多测试指数为n(本身层数)
  15.         }
  16.         for (int j = 2;j <= 3;j++) // 循环手机部数 ,从2开始,因为1已经知道了
  17.         {
  18.                 for (int i = 1;i <= 1000;i++) // 循环楼层数
  19.                 {
  20.                         dp[i][j] = dp[i - 1][j] + 1; // 第j层楼还有i部手机时的测试次数=第j-1层楼还有i部手机时测试次数加1
  21.                         for (int k = 2;k <= i;k++) // 假设从第k层摔手机
  22.                         {
  23.                                 dp[i][j] = min(dp[i][j], max(dp[k - 1][j - 1], dp[i - k][j]) + 1);
  24.                         }
  25.                 }
  26.         }
  27.         cout << dp[1000][3] << endl;
  28.         return 0;
  29. }
  30. // 答案19
复制代码

5E:取数位(代码填空9分)


        快速排序,就是每次选择一个数,然后做比力使得左边的数小于所选择的数,右边的数大于所选择的数。然后将左右双方在举行快速排序。
题目答案:
  1. a, i+1, r, k-(i-l+1)
复制代码

6F:递增三元组(编程题11分)(前缀和)




剖析代码

排序 + 双指针
        分析题目我们可以发现三元组中b[j] 可以同时制约 a 和 c[k],由此可以先排序 后枚举b 对于每个 b 我们找到比它大的c[k] 的数目和比它小的a的数目,因为我们排过序全部 a,b,c 只需遍历一遍即可。
  1. #include <bits/stdc++.h>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. using namespace std;
  6. #define endl '\n'
  7. #define int long long
  8. signed main()
  9. {
  10.         ios::sync_with_stdio(0);
  11.         cin.tie(0);
  12.         cout.tie(0);
  13.         int n = 0;
  14.         cin >> n;
  15.         vector<int> A, B, C;
  16.         for (int t = 0; t != 3; ++t)
  17.         {
  18.                 for (int i = 0; i != n; ++i)
  19.                 {
  20.                         int a = 0;
  21.                         cin >> a;
  22.                         if (t == 0)
  23.                                 A.push_back(a);
  24.                         else if (t == 1)
  25.                                 B.push_back(a);
  26.                         else
  27.                                 C.push_back(a);
  28.                 }
  29.         }
  30.         sort(A.begin(), A.end());
  31.         sort(B.begin(), B.end());
  32.         sort(C.begin(), C.end());
  33.         int i, j, k;
  34.         i = j = k = n - 1;
  35.         int res = 0;
  36.         while (j >= 0)
  37.         {
  38.                 while (k >= 0 && B[j] < C[k])
  39.                         --k;
  40.                 while (i >= 0 && A[i] >= B[j])
  41.                         --i;
  42.                 res += (n - k - 1) * (i + 1);
  43.                 --j;
  44.         }
  45.         cout << res << endl;
  46.         return 0;
  47. }
复制代码

7G:螺旋折线(编程题19分)




剖析代码

找规律+模仿
        这道题的解法为 先找各个极点坐标对应的长度,我们可以发现极点 (-1,0) (-1,1) (1,1) (1 ,-1) (-2,-1) (-2,2)对应长度 1 1+1 1+1+2 1+1+2+2 1+1+2+2+3 1+1+2+2+3+3发现规律。细节的我们找到极点的规律之后,给我们一个点我们先判定它在谁人环上,然后求出对应极点的长度,最后加或减即可
  1. #include <bits/stdc++.h>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cmath>
  7. using namespace std;
  8. #define endl '\n'
  9. #define int long long
  10. signed main()
  11. {
  12.         ios::sync_with_stdio(0);
  13.         cin.tie(0);
  14.         cout.tie(0);
  15.         int x, y, t, ans;
  16.         cin >> x >> y;
  17.         int abx = abs(x), aby = abs(y);
  18.         if (x >= 0 && y >= 0) // 第一象限
  19.         {
  20.                 t = max(abx, aby);
  21.                 ans = (t * 2 - 1) * (t * 2 - 1 + 1);
  22.                 if (abx == t)
  23.                         ans += t * 2 + t - aby;
  24.                 else
  25.                         ans += t + abx;
  26.         }
  27.         else if (x > 0 && y < 0) // 第四象限
  28.         {
  29.                 t = max(abx, aby);
  30.                 ans = (t * 2 - 1) * (t * 2 - 1 + 1);
  31.                 if (abx == t)
  32.                         ans += 3 * t + aby;
  33.                 else
  34.                         ans += 4 * t + t - abx;
  35.         }
  36.         else if (x <= 0 && y <= 0) // 第三象限
  37.         {
  38.                 t = max(abx - 1, aby);
  39.                 ans = (t * 2) * (t * 2 + 1);
  40.                 if (abx - 1 == t)
  41.                         ans += 2 * t + 1 + t - aby;
  42.                 else
  43.                         ans += t + abx;
  44.         }
  45.         else // 第二象限
  46.         {
  47.                 t = max(abx, aby);
  48.                 ans = (t * 2 - 1) * (t * 2 - 1 + 1);
  49.                 if (abx == t)
  50.                         ans -= t - aby;
  51.                 else
  52.                         ans += t - abx;
  53.         }
  54.         cout << ans << endl;
  55.         return 0;
  56. }
复制代码

8H:日志统计(编程题21分)





剖析代码(过78%数据)

哈希+排序
        用哈希存储每个id的全部点赞的时间数据,然后遍历哈希,将时间排序再用双指针查抄是否有区间D符合热帖要求。
  1. #include <bits/stdc++.h>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <cmath>
  6. #include <string>
  7. #include <vector>
  8. #include <unordered_map>
  9. using namespace std;
  10. #define endl '\n'
  11. #define int long long
  12. signed main()
  13. {
  14.         ios::sync_with_stdio(0);
  15.         cin.tie(0);
  16.         cout.tie(0);
  17.         int N, D, K;
  18.         cin >> N >> D >> K;
  19.         unordered_map<int, vector<int>> map;
  20.         for (int i = 0; i != N; i++)
  21.         {
  22.                 int ts, id;
  23.                 cin >> ts >> id;
  24.                 map[id].push_back(ts);
  25.         }
  26.         vector<int> ans;
  27.         for (auto& m : map)
  28.         {
  29.                 int n = m.second.size();
  30.                 if (n < K)continue;
  31.                 sort(m.second.begin(), m.second.end());
  32.                 int i = 0, j = 0;
  33.                 int temp = 0;
  34.                 while (j < n && i < n)
  35.                 {
  36.                         if (n - i < K)
  37.                                 break;
  38.                         while (j < n && m.second[j] - m.second[i] < D)
  39.                         {
  40.                                 temp++;
  41.                                 j++;
  42.                                 if (temp >= K)
  43.                                         break;
  44.                         }
  45.                         if (temp >= K)
  46.                         {
  47.                                 ans.push_back(m.first);
  48.                                 break;
  49.                         }
  50.                         i++;
  51.                         temp--;
  52.                 }
  53.         }
  54.         sort(ans.begin(), ans.end());
  55.         for (auto e : ans)
  56.         {
  57.                 cout << e << endl;
  58.         }
  59.         return 0;
  60. }
复制代码

9I:举世变暖(编程题23分





剖析代码

记录改变前和改变后的海疆情况 然后计数
必要留意的是不能简单通过 计算原来的 和 后来的岛屿数差值来计算答案
原因是 例如:
  1. ........
  2. .##.....
  3. .####...
  4. ..#.#...
  5. ...###..
  6. ...###..
  7. ........
  8. ........
复制代码
这种情况原来只有一个岛屿 改变后 却有2个
计数的方法为遍历原来的每个岛屿,只要这个岛屿改变后不存在任意一个元素,那么ans++;
  1. #include<iostream>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<string>
  5. using namespace std;
  6. typedef long long ll;
  7. int dis[][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
  8. bool sign;
  9. void dfs(vector<vector<int>>& a, int i, int j, vector<vector<int>>& b){
  10.         if (i<1 || i>a.size() - 1 || j<1 || j>a.size() - 1||a[i][j]==0){
  11.                 return;
  12.         }
  13.         a[i][j] = 0;
  14.         if (b[i][j] != 0)sign = false;
  15.         for (int k = 0; k != 4; k++){
  16.                 dfs(a, i + dis[k][0], j + dis[k][1],b);
  17.         }
  18. }
  19. int main()
  20. {
  21.         int N;
  22.         cin >> N;
  23.         vector<vector<int>> before;
  24.         vector<vector<int>> later;
  25.         for (int i = 0; i != N; i++){
  26.                 before.push_back(vector<int>());
  27.                 for (int j = 0; j != N; j++){
  28.                         char t;
  29.                         cin >> t;
  30.                         if (t == '.')before[i].push_back(0);
  31.                         else before[i].push_back(1);
  32.                 }
  33.         }
  34.         later = before;
  35.         for (int i = 1; i != N - 1; i++){
  36.                 for (int j = 1; j != N - 1; j++){
  37.                         if (later[i][j] == 1){
  38.                                 bool b = true;
  39.                                 for (int k = 0; k != 4; k++){
  40.                                         if (before[i + dis[k][0]][j + dis[k][1]] == 0){
  41.                                                 b = false;
  42.                                         }
  43.                                 }
  44.                                 if (!b)later[i][j] = 0;
  45.                         }
  46.                 }
  47.         }
  48.         int ans = 0;
  49.         for (int i = 1; i != N - 1; i++){
  50.                 for (int j = 1; j != N - 1; j++){
  51.                         if (before[i][j]){
  52.                                 sign = true;
  53.                                 dfs(before, i, j,later);
  54.                                 if (sign)ans++;
  55.                         }
  56.                 }
  57.         }
  58.         cout << ans << endl;
  59.        
  60.         system("pause");
  61.         return 0;
  62. }
复制代码

10J:乘积最大(编程题25分)




剖析代码

思路
1、如果k== n的话,那么全部数字都要选
2、如果k%2== 0(即k为偶数),那么选出来的一个好坏负数
3、如果k%2== 1(即k为奇数)分两种:
(1)如果全部都为负数,那么全部都为负数,把最大最大负数取出来,然后变成了k为偶数的情况,要把符号改变过来
(2)否则的话,则肯定至少有 1个非负数, 那么我们将最大的数取出来,然后变成了k为偶数的情况。
  1. #include<bits/stdc++.h>
  2. #define x first
  3. #define y second
  4. #define mem1(h) memset(h,-1,sizeof h)
  5. #define mem0(h) memset(h,0,sizeof h)
  6. #define mcp(a,b) memcpy(a,b,sizeof b)
  7. using namespace std;
  8. typedef long long LL;
  9. typedef unsigned long long ull;
  10. typedef pair<int,int>PII;
  11. typedef pair<double,double>PDD;
  12. namespace IO{
  13.     inline LL read(){
  14.         LL o=0,f=1;char c=getchar();
  15.         while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
  16.         while(c>='0'&&c<='9'){o=o*10+c-'0';c=getchar();}
  17.         return o*f;
  18.     }
  19. }using namespace IO;
  20. //#############以上是自定义技巧(可忽略)##########
  21. const int N=1e5+7,M=2e5+7,INF=0x3f3f3f3f,mod=1e9+9,P=131;
  22. int n,k;
  23. int a[N];
  24. int main(){
  25.     cin>>n>>k;
  26.     for(int i=0;i<n;i++){
  27.         cin>>a[i];
  28.     }
  29.     sort(a,a+n);
  30.     int res=1;
  31.     int l=0,r=n-1;
  32.     int sign=1;
  33.     if(k&1){//k为奇数
  34.         res=a[r--];//取最大的数
  35.         k--;
  36.         if(res<0)sign=-1;//如果是最大为负数,要改变符号
  37.     }
  38.     while(k){//k为偶数的情况
  39.         LL x=(LL)a[l]*a[l+1],y=(LL)a[r]*a[r-1];//取最小的两个与最大两个数乘积
  40.         if(x*sign>y*sign){//看两个数与当前符号相乘哪个大取哪个
  41.             res=x%mod*res%mod;
  42.             l+=2;
  43.         }else{
  44.             res=y%mod*res%mod;
  45.             r-=2;
  46.         }
  47.         k-=2;
  48.     }
  49.     cout<<res<<endl;
  50.     return 0;
  51. }
复制代码
本篇完。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

八卦阵

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表