2022年第十四届蓝桥杯C/C++省赛研究生组(前四题)

打印 上一主题 下一主题

主题 1691|帖子 1691|积分 5073

 Question1 :工作时长(5分)

   【题目描述】
         小蓝手里有一份 20222022 年度自己的上班打卡记录文件,文件包罗多少条打卡记录,每条记录的格式均为“yyyy-MM-dd HH:mm:ssyyyy-MM-dd HH:mm:ss”,即按照年-月-日 时:分:秒的形式记录着一个时间点(接纳 2424 小时进制)。由于某些原因,这份文件中的时间记录并不是按照打卡的时间次序记录的,而是被打乱了。但我们包管小蓝每次上班和放工时都会正常打卡,而且正好打卡一次,别的时候不会打卡。每一对相邻的上-放工打卡之间的时间就是小蓝本次的工作时长,例如文件内容如下的话:
    

  
          表示文件中共包罗了两段上放工记录,1)20222022-01010101 0707:5858:02∼202202∼2022-0101-0101 1212:0000:0505,工作时长为 1452314523 秒;2)20222022-0101-0101 1616:0101:35∼202235∼2022-0101-0202 0000:2020:0505,工作时长为 2991029910 秒;工作时长一共是 14523+29910=4443314523+29910=44433 秒。现在小蓝想知道在 20222022 年度自己的工作时长一共是多少秒?
【答案提交】
        这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
  Result:  5101913
Solve: 把文件数据复制到excel中,把第一列分列,只保留时分秒,改变前三列的格式(选中时间列(A,B,C列)右键选择“设置单位格格式),单位格格式设置为 [h]:mm:ss,分别对B列设置公式=A2-A1,下拉填充,C列求SUM(B:B),得到初始结果,转换得到终极结果。

Code:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main(){
  4.         long long ans = 1417 * 3600 + 11 * 60 + 53;
  5.         cout << ans << endl;
  6.         return 0;
  7. }
复制代码
Question2 :字串数字(5分)

   【题目描述】        
          小蓝有一张门电路的逻辑图,如下图所示:
                  

          图中每个三角形代表着一种门电路,可能是与门、或门、异或门中的任何一种,它继承上一层中的两个圆形中的数据作为输入,产生一个输出值输出到 下一级 (如图中箭头所示)。图中圆形表示的是暂存的输出结果,取值只可能是 0 或 1,为了便于表示我们用 arr[j] 表示第 i(0≤i≤4)行第 j(0≤j≤i) 个圆形的值。此中 arr⁡[0]=(In⁡[0],In⁡[1],In⁡[2],In⁡[3],In⁡[4])表示的是输入数据,对于某个 arr⁡[j](i≤0),盘算方式为arr[j]=arr[i−1][j] op arr⁡[i−1][j+1],此中 op 表示的是将 arr⁡[i−1][j]、arr[i−1][j+1] 作为输入,将 arr⁡[j] 作为输出的那个门电路, 与门、或门、异或门分别对应于按位与 $(&) 、$ 按位或(1) 、按位异或 (^) 运算符。
  现在已知输入为 In⁡[0]=1,In⁡[1]=0,In⁡[2]=1,In⁡[3]=0,In⁡[4]=1,小蓝想要使得终极的输出 Out 的值为 1, 叨教一共有多少种不同的门电路组合方式?此中上图中表现的就是一种正当的方式。
【答案提交】
          这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
  Result:  30528
Solve:


  • 枚举全部可能的操作组合(&、|、^),共 3^(n*(n-1)/2) 种。
  • 对每种操作组合,逐层盘算数组 arr,并查抄终极结果是否为 1。
Code:
  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5.   int arr[5][5] = {{1,0,1,0,1}};
  6.   int t = 1,ans = 0,u,s;
  7.   int f[3] = {0,1,2};
  8.   for(int i = 0;i < 10;i ++){   //所有枚举次数
  9.     t = t * 3;
  10.   }
  11.   for(u = 0;u < t;u ++){
  12.     s = u;
  13.     for(int i = 1;i < 5;i ++){
  14.       for(int j = 0;j < 5 - i;j ++){
  15.         int a = s % 3;  //三进制取余数
  16.         s /= 3;         //更新 s,以便提取下一个操作类型,保证它每一种操作类型都能取到
  17.         switch(a){
  18.           case 0: arr[i][j] = arr[i - 1][j] & arr[i - 1][j + 1];break;
  19.           case 1: arr[i][j] = arr[i - 1][j] | arr[i - 1][j + 1];break;
  20.           case 2: arr[i][j] = arr[i - 1][j] ^ arr[i - 1][j + 1];break;
  21.           default : cout << "出错" << endl;
  22.         }
  23.       }
  24.     }
  25.     if(arr[4][0] == 1) ans ++;
  26.   }
  27.   cout << ans << endl;
  28.   return 0;
  29. }
复制代码
Question3 :翻转(10分)

   【问题描述】
        小蓝用黑白棋的 几 个棋子排成了一行,他在脑海里想象出了一个长度为n 的 01 串 T,他发现如果把黑棋当做 1,白棋当做 0,这一行棋子也是一个长度为n的 01串S.
        小蓝决定,如果在 S 中发现一个棋子和它两边的棋子都不一样,就可以将其翻转变成另一个颜色。也就是说,如果S 中存在子串 101或者 010,就可以选择将其分别变为 111和 000,如许的操作可以无穷重复。
        小蓝想知道最少翻转多少次可以把 S 变成和 T 千篇一律。
【输入格式】
        输入包罗多组数据。
          输入的第一行包罗一个正整数 DD 表示数据组数。
          后面 2D 行每行包罗一个 01 串,每两行为一组数据,第 2i−1 行为第 i 组数据的 Ti​,第 2i 行为第 i 组数据的 Si​,Si​ 和 Ti​ 长度均为 ni​。
  【输出格式】
          对于每组数据,输出一行包罗一个整数,表示答案,如果答案不存在请输出 −1。
  【样例输入】
          2
          1000111
          1010101
          01000
          11000
  【样例输出】
          2
          -1
  Solve:
  需要注意:  


  • 最左和最右的棋子无法翻转.
  • 一颗棋子在翻转后无法再翻转返来,因此每个位置最多翻转一次.
  • 一颗棋子翻转后,与它相邻的棋子无法进行翻转.
  • S 与 T 棋子不同的位置必须要翻转.
Code:
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. vector<string> arr;
  4. int main()
  5. {
  6.   int n;
  7.   cin >> n;
  8.   cin.ignore();    // 清除输入缓冲区中的换行符
  9.   arr.resize(2 * n);  // 调整 arr 的大小
  10.   vector<int> ans;          // 存储每对字符串的结果
  11.   for(int i = 0;i < 2 * n;i += 2){
  12.           string line1,line2;
  13.     getline(cin,line1);
  14.     arr[i] = line1;
  15.     getline(cin,line2);
  16.     arr[i + 1] = line2;
  17.     int an = 0;
  18.     for(int j = 0;j < arr[i].size();j ++){
  19.       if(arr[i][j] != arr[i + 1][j]){
  20.         if(j == 0 || j == arr[i].size() - 1){
  21.           an = -1;
  22.           break;
  23.         }
  24.         else if(arr[i + 1][j - 1] != arr[i + 1][j] && arr[i + 1][j + 1] != arr[i + 1][j]){
  25.           an ++;
  26.         }
  27.         else{
  28.           an = -1;
  29.           break;
  30.         }
  31.       }
  32.     }
  33.         ans.push_back(an);
  34.   }
  35.   for(int i = 0;i < n;i ++){
  36.           cout << ans[i] << endl;
  37.   }
  38.   return 0;
  39. }
复制代码
  Question4 :阶乘的和(10分)

   【题目描述】
  

  【输入格式】
        输入的第一行包罗一个整数 n。
         第二行包罗 n 个整数,分别表示 Ai​,相邻整数之间使用一个空格分隔。
  【输出格式】
          输出一行包罗一个整数表示答案。
  【样例输入】
          3
          2 2 2
  【样例输出】
          3
  Solve:
使用暴力解题,会超时。
注意:6个1!=3个2!=1个3!  
归纳出来就是 n 个 k!,可以转换成n / (k+1) 个 (k+1)!, 前提条件是n%(k+1)==0。
sum=A!+B!+C!+D!+......由小到大
m!是sum的最大公因数,一定是A,B,C,....中公共部分的阶乘
由于A,B,...是从小到的阶乘,所以我们可以从小阶乘开始操作,A!可以试着B!归并,如果不能归并那么结果就是A! 否则,A和B归并,继承进入这个判断。
Code:
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. map<ll, int>mp;
  5. int main ()
  6. {
  7.   int n;
  8.   cin >> n;
  9.   for (int i = 0; i < n; i++)
  10.   {
  11.     ll temp;
  12.     cin >> temp;
  13.     mp[temp]++;
  14.   }
  15.   map<ll, int>::iterator it;
  16.   for (it = mp.begin(); it != mp.end(); it++)
  17.   {
  18.     ll num = it->first;
  19.     int cnt = it->second;
  20.     if (cnt % (num + 1) == 0)
  21.     {
  22.       mp[num + 1] += cnt / (num + 1);
  23.     }
  24.     else
  25.     {
  26.       cout << num << endl;
  27.       return 0;
  28.     }
  29.   }
  30.   return 0;
  31. }
复制代码
声明:题目信息均泉源于蓝桥杯官网,以个人刷题整理为目标,如若侵权,请接洽删除~

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

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

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

本版积分规则

冬雨财经

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表