2020第十一届7月蓝桥杯大赛软件类B组C/C++省赛题解

试题 A:跑步训练(结果填空)

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

#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<int, int> mii;
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 = 210;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int solve() {
    
    
  int x = 10000, res = 0;
  while(1) {
    
    
    _for(0, 60, i) {
    
    
      x -= 10; ++res;     
      if(x <= 0) return res;
    }
    x += 300; res += 60;
  }
}
int main() {
    
    
  cout << solve();
  return 0;
}

答案: 3880(注意答案是以秒为单位输出!)


试题 B:纪念日(结果填空)

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

答案:52038720(36138 * 24 * 60)


试题 C:合并检测(结果填空)

题意
在这里插入图片描述
做法概率杀我 ,设A国共有100人,那么合并检测需要用的试剂为 100 k \frac{100}{k} k100个,均匀分布可以认为100个人里面就有一个人感染,所以,对于这一个人还需要个试剂,结果就是 100 k + k \frac{100}{k}+k k100+k,根据基本不等式,当 100 k = k \frac{100}{k}=k k100=k时,等式取到最小值,这时k=10。

答案:10


试题 D:REPEAT 程序(结果填空)

题意
在这里插入图片描述
在这里插入图片描述
做法:用一个栈维护循环次数,模拟即可。
代码

#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<int, int> mii;
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 = 210;
const LL Mod = 1e9+7;
const int M = 1e6+10;
string s;
stack<int> sk;
int main() {
    
    
  freopen("prog.txt", "r", stdin);
  int ci = 1;
  LL res = 0;
  while(getline(cin, s)) {
    
    
    int pos = 0, len = s.size(), sj, mid;
    while(pos < len && s[pos] == ' ') ++pos;
    sj = pos / 4;
    while(sk.size() > sj) {
    
    
      ci /= sk.top();
      sk.pop();
    }
    if(s[pos] == 'R') {
    
    
      pos += 7;
      for(mid = 0; pos < len-1; ++pos) mid = mid * 10 + s[pos]-'0';
      sk.push(mid); ci *= mid;
    } else {
    
    
      pos += 8;
      for(mid = 0; pos < len; ++pos) mid = mid * 10 + s[pos]-'0';
      res += mid * ci;
    }
    //cout << mid << endl; 
  }
  cout << res;
  return 0;
}

答案:241830


试题 E:矩阵(结果填空)

题意
在这里插入图片描述
做法:一看这题像dp,但是想不出转移方程 。f[i][j]表示第一行选i个数,第二行选j个数的总方案数,第二行能选的前提是第一行第j列有数。每个状态由上一个行和上一列转化而来,可以选择放在第一行或者第二行。这篇题解简单易懂。

代码

#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<int, int> mii;
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 = 1020;
const int Mod = 2020;
const int M = 2020;
int f[N][N];
int main() {
    
    
  f[0][0] = 1;
  _for(0, N, i) _for(0, N, j) {
    
    
    if(i > j) f[i][j] = (f[i][j] + f[i-1][j]) % Mod; //放在第二行
    if(j) f[i][j] = (f[i][j] + f[i][j-1]) % Mod; //放在第一行
  }
  cout << f[1010][1010];
  return 0;
}

答案:1340

——以下题目通过了 AcWing 的数据测试——

试题 F:整除序列(程序设计)

题意
在这里插入图片描述

做法:记得开long long!!

代码

#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<int, int> mii;
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 = 1020;
const int Mod = 2020;
const int M = 2020;
int main() {
    
    
  LL n; scanf("%lld", &n);
  printf("%lld", n);
  n >>= 1;
  while(n) {
    
    
    printf(" %lld", n);
    n >>= 1;
  }
  return 0;
}

试题 G:解码(程序设计)

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

做法内部可能有数字有两位以上的情况,坑还是挺多的。 由于题中指出不会超过9个相同字母写成缩写形式,所以不会出现有两位数字的情况(不过以下代码还是考虑了这种情况)。多谢评论区大佬指出问题所在。

代码

#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<int, int> mii;
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 = 1020;
const int Mod = 2020;
const int M = 2020;
string s;
int main() {
    
    
  cin >> s;
  int len = s.size(), pos = 0, mid;
  char lst;
  while(pos < len) {
    
    
    if(isdigit(s[pos])) {
    
    
      mid = 0;
      while(pos < len && isdigit(s[pos])) mid = mid * 10 + s[pos] - '0', ++pos;
      --mid; 
      _for(0, mid, i) printf("%c", lst);
    } else printf("%c", s[pos]), lst = s[pos++];
  }
  puts("");
  return 0;
}

试题 H:走方格(程序设计)

题意
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
做法:类似一个经典的dp,方格取数,只要行数和列数都为偶数时不更新dp[i][j]就能做到。
代码

#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<int, int> mii;
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 = 40;
const int Mod = 2020;
const int M = 2020;
LL dp[N][N];
int main() {
    
    
  int n, m;
  scanf("%d%d", &n, &m);
  dp[1][1] = 1;
  _rep(1, n, i) _rep(1, m, j) {
    
    
    if(i==1 && j==1) continue;
    if((i&1) || (j&1)) dp[i][j] = dp[i-1][j] + dp[i][j-1];
  }
  printf("%lld\n", dp[n][m]);
  return 0;
}

试题 I:整数拼接(程序设计)

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

做法:正解就是把所有数扩大几倍后存起来,再用map找,要理解到,对于这些存起来的数字取膜k以后,只有两个数字加起来%k等于0才算一对,后面就能暴力了。用数组存每个数扩大10倍、100倍…十的十次方倍,存入a数组,再用一个vis充当map的作用,顺势记录这个数有多少位。
代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL a[N][11], x, mid;
int vis[N][11], n, k;
int cw(LL x) {
    
    
	int res = 0;
	while(x) {
    
    
		++res; x /= 10;
	}
	return res;
}
int main() {
    
    
	scanf("%d%d", &n, &k);
	for(int i = 0; i < n; ++i) {
    
    
		scanf("%lld", &x);
		++vis[x%k][cw(x)]; a[i][0] = x;
		for(int j = 1; j <= 10; ++j) a[i][j] = a[i][j-1] * 10 % k;
	}
	LL res = 0;
	for(int i = 0; i < n; ++i) {
    
    
		for(int j = 1; j <= 10; ++j) {
    
    
			mid = k - a[i][j]; mid %= k;
			if(vis[mid][j]) {
    
    
				res += vis[mid][j];
				if(a[i][0]%k == mid && cw(a[i][0]) == j) --res;
			}
		}
	}
	
	printf("%lld\n", res);
	return 0;
}

试题 J:网络分析(程序设计)

题意
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
做法:用w数组记录该点所有子孙都需要+的权值,每次合并都下传标记,复杂度n^2,极限卡常

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
int w[N], fa[N], res[N];
int Find(int x) {
    
    
  return fa[x] == x ? x : fa[x] = Find(fa[x]);
} 
int n, m;
void Merg(int x, int y) {
    
    
  int fx = Find(x), fy = Find(y);
  if(fx != fy) {
    
    
    for(register int i = 1; i <= n; ++i) res[i] += w[Find(i)];
    memset(w, 0, sizeof w);
    fa[fx] = fy;
  }
  return;
}
int main() {
    
    
  scanf("%d%d", &n, &m);
  for(int i = 1; i <= n; ++i) fa[i] = i;
  int opt, a, b;
  while(m--) {
    
    
    scanf("%d%d%d", &opt, &a, &b);
    if(opt == 1) Merg(a, b);
    else w[Find(a)] += b;
  }
  for(int i = 1; i <= n; ++i) printf("%d%c", res[i]+w[Find(i)], i==n?'\n':' ');
  return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/108165611