2019第十届蓝桥杯大赛软件类B组C/C++省赛题解

试题A:组队(结果填空)

题意
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
答案:490


试题B:年号字串(结果填空)

题意在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    
    
  int n = 2019;
  string s = "";
  while(n) {
    
    
    s = (char)(n%26+'A'-1) + s;
    n /= 26;
  }
  cout << s;
  return 0;
}

答案: BYQ


试题 C: 数列求值(结果填空)

题意在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 3e7+10;
const int Mod = 1e5;
int a[N];
int main() {
    
    
  a[1] = a[2] = a[3] = 1;
  for(int i = 4; i <= 20190324; ++i) {
    
    
    a[i] = (a[i-1] + a[i-2] + a[i-3]) % Mod;
  }
  cout << a[20190324];
  return 0;
}

答案: 4659


试题 D: 数的分解(结果填空)

题意
在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 3e7+10;
const int Mod = 1e5;
int check(int i) {
    
    
  while(i) {
    
    
    if(i%10 == 2 || i%10 == 4) return 0;
    i /= 10;
  }
  return 1;
}
int main() {
    
    
  int n = 2019, sum = 0;
  for(int i = 1; i < n - 1; ++i) {
    
    
    if(!check(i)) continue;
    for(int j = i+1; j < n; ++j) {
    
    
      if(!check(j)) continue;
      for(int k = j+1; k <= n; ++k) {
    
    
        if(check(k)&&i + j + k == 2019)
          ++sum;
      }
    }
  }
  printf("%d\n", sum);
  return 0;
}

答案: 40785


试题 E: 迷宫(结果填空)

题意在这里插入图片描述

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

在这里插入图片描述

代码

#include<bits/stdc++.h>
using namespace std;
const int ne[4][2] = {
    
    1, 0, 0, -1, 0, 1, -1, 0}; // D L R U
char s[10] = "DLRU";
const int N = 50;
struct xx {
    
    
  int x, y;
  string dir;
}cur, nt; 
int n = 30, m = 50, vis[N][N];
char tu[N][N];
void bfs() {
    
    
  queue<xx> q;
  cur.x = 1; cur.y = 1; cur.dir = "";
  q.push(cur); vis[1][1] = 1;
  while(!q.empty()) {
    
    
    cur = q.front(); q.pop();
    if(cur.x == 30 && cur.y == 50) {
    
    
      cout << cur.dir; return;
    } 
    for(int i = 0, tx, ty; i < 4; ++i) {
    
    
      tx = cur.x + ne[i][0]; ty = cur.y + ne[i][1];
      if(tx < 1 || ty < 1 || tx > n || ty > m || vis[tx][ty] || tu[tx][ty] == '1') continue;
      nt.x = tx; nt.y = ty; nt.dir = cur.dir + s[i];
      q.push(nt); vis[tx][ty] = 1; 
      
    }
  }
}
int main() {
    
    
  for(int i = 1; i <= 30; ++i) {
    
    
    for(int j = 1; j <= 50; ++j) {
    
    
      scanf("%c", &tu[i][j]);
    }
  }
  bfs();
  return 0;
} 

答案:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR


试题 F: 特别数的和(程序设计)

题意
在这里插入图片描述
做法:从1到n每一个枚举判断就好啦

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 1e4+10;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int main() {
    
    
  int n; scanf("%d", &n);
  LL res = 0;
  for(int i = 1, f, ii; i <= n; ++i) {
    
    
    ii = i; f = 0;
    while(ii) {
    
    
      if(ii%10 == 2 || ii%10 == 0 || ii%10 == 1 || ii%10 == 9) {
    
    
        f = 1; break;
      }
      ii /= 10;
    }
    if(f) res += i;
  }
  printf("%lld\n", res);
  return 0;
}

试题 G: 完全二叉树的权值(程序设计)

题意
在这里插入图片描述

做法:本意应该是考完全二叉树的定义,就是满二叉树的最后一层右边可能会缺少一点,然后满二叉树的性质有每一层都是 2 i − 1 2^{i-1} 2i1个元素,每一次更新标记就好啦。

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 2e6+10;
const LL Mod = 1e9+7;
const int M = 2e6+10;
int a[N];
int main() {
    
    
   int n, x, x1 = 0, x2 = 1; scanf("%d", &n);
   LL mid = 0, midi = 1, res = 0, resi = -1;
   _rep(1, n, i) {
    
    
     scanf("%d", &x);
     mid += x; ++x1;
     if(x1 == x2) {
    
    
       if(res < mid) res = mid, resi = midi;
       ++midi; x1 = mid = 0; x2 *= 2;
     }
   } 
   if(res < mid) resi = midi;
   printf("%lld\n", resi);
  return 0;
}

试题 H: 等差数列(程序设计)

题意
在这里插入图片描述
在这里插入图片描述

做法:找到数组中每两个差值的最大公约数,这会是这个等差数列的最大公差,公差最大意味着数的数量越小,数量可以用等差数列an的通项公式计算,最后特判一下d=0的情况就可以啦。

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 1e5+10;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int a[N];
int main() {
    
    
  int d;
  int n; scanf("%d", &n);
  for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
  sort(a, a+n);
  for(int i = 1; i < n; ++i) d = __gcd(d, a[i]-a[i-1]);
  if(!d) printf("%d\n", n);
  else printf("%d\n", (a[n-1]-a[0])/d+1);
  
  return 0;
}

试题 I: 后缀表达式(程序设计)

题意
在这里插入图片描述

做法:这题一开始我也没想到有这么多情况需要讨论,忽略了负数和减号,以及后缀表达式中其实能组出括号的形式,括号是真的很神奇 ,出在OI赛制里确实能拖一大批人下水,共分为一下几种情况:

  • 无减号:就是所有数的和啦
  • 有减号:
    • 无负数:结果是减去最小的正数,可以化成这样的形式,a+b+c-(d-e-f) [d,e,f为负数]。
    • 有部分负数:那么这些负数都可以变成正数加起来。
    • 全是负数:只有最大的负数需要加,其他负数都能减掉。

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 2e5+10;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int a[N];
int main() {
    
    
  int n, m, cnt = 0;
  LL res = 0;
  scanf("%d%d", &n, &m);
  for(int i = 0; i <= n+m; ++i) {
    
    
    scanf("%d", &a[i]); res += a[i]; 
    if(a[i] < 0) ++cnt;
  }
  sort(a, a+n+m+1);
  if(m) {
    
     //有减号 
    if(cnt) {
    
     // 有负数 
      if(cnt != n+m+1) _for(0, cnt, i) res -= 2*a[i]; //有减号和负数,且并不全为负 
      else _for(0, cnt-1, i) res -= 2*a[i]; //有减号和负数,且全为负数 
    } else res -= 2*a[0]; //有减号无负数 
  } 
  printf("%lld\n", res);
  return 0;
}

试题 J: 灵能传输(程序设计)

题意
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
做法:首先需要知道进行一次能量转移的操作等同于在能量前缀和上交换两个数字,那么,就意味着前缀和除了S0和Sn,其他可以打乱顺序,问题变形为,把前缀和数组sum,固定开头和结尾两个点,令中间的数打乱顺序,使得任意两个数之差的最大值最小。画图后会发现有以下几种情况:
在这里插入图片描述
所以要做的就是分类讨论构造波形,我的方法是用三个数组记录上部分波形和下部分波形以及中间部分波形,并且因为图形是对称的,那么对于第三种情况,我是将Sn和S0交换当作第一种情况考虑,细节有很多。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5+10;
const int INF = 0x3f3f3f3f;
LL a[N], sum[N];
vector<LL> a1, a2, a3;
int main() {
    
    
  int T; scanf("%d", &T);
  int n;
  while(T--) {
    
    
    a1.clear(); a2.clear(); a3.clear();
    scanf("%d", &n);
    for(int i = 1, x; i <= n; ++i) {
    
    
      scanf("%d", &x);
      a[i] = a[i-1] + x;
    }
    LL m1 = 0, m2 = a[n];
    if(m1 > m2) swap(m1, m2);
    for(int i = 1; i < n; ++i) {
    
    
      if(a[i] < m1) a1.push_back(a[i]);
      else if(a[i] > m2) a3.push_back(a[i]);
      else a2.push_back(a[i]);
    }
    sort(a1.begin(), a1.end()); sort(a2.begin(), a2.end()); sort(a3.begin(), a3.end()); 
    sum[0] = m1; sum[n] = m2;
    int len = a1.size(), k = 0;
    if(len & 1) {
    
    
      for(int i = len-2; i >= 1; i -= 2) sum[++k] = a1[i];
      for(int i = 0; i < len; i += 2) sum[++k] = a1[i];  
    }  else {
    
    
      for(int i = len-2; i >= 0; i -= 2) sum[++k] = a1[i];
      for(int i = 1; i < len; i += 2) sum[++k] = a1[i];
    
    }
     
    len = a2.size();
    for(int i = 0; i < len; ++i) sum[++k] = a2[i];
    
    len = a3.size();
    for(int i = 0; i < len; i += 2) sum[++k] = a3[i];
    k = n;
    for(int i = 1; i < len; i += 2) sum[--k] = a3[i];
    LL res = -INF;
    for(int i = 1; i <= n; ++i) res = max(res, abs(sum[i]-sum[i-1]));
    
    printf("%lld\n", res);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/107989001
今日推荐