2019年第十届蓝桥杯国赛C++A组
蓝桥杯历年国赛真题汇总:Here
最后编辑时间:
2021年5月27日
统一声明
如果不写默认带有常用头文件
如果不表明主函数默认表示在 void solve(){}
默认使用
using namespace std;
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using ll = long long;
填空题答案速览
- 180414
试题 A: 三升序列
【问题描述】
对于一个字母矩阵,我们称矩阵中的一个三升序列是指在矩阵中找到三个 字母,它们在同一行,同一列,或者在同一 45 度的斜线上,这三个字母从左向 右看、或者从上向下看是递增的。
例如,如下矩阵中
YQPD
BKEZ
AFYV
有BKZ、BEZ、AFY、AFV、AKP、DEF 等 6 个三升序列。注意当三个字母 是从左下到右上排列时,从左向右看和从上向下看是不同的顺序。
对于下面的 30 行 50 列的矩阵,请问总共有多少个三升序列?(如果你把 以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在 试题目录下有一个文件 inc.txt,内容与下面的文本相同)
VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG
SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF
ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA
BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL
YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH
ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU
XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR
ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG
MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA
VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF
GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC
EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK
PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW
CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP
RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS
PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR
JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL
YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP
HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN
DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF
LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW
CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ
IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI
ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB
HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP
FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS
VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ
BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR
RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY
ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX
答案:180414
#include<bits/stdc++.h>
using namespace std;
char text[30][500];
void copytext() {
char c[500];
int line = 0;
FILE *fp = fopen("inc.txt", "r");
if (fp == NULL) {
cout << "failed to open file!" << endl;
} else {
while (fgets(c, 500, fp))
strcpy(text[line++], c);
}
fclose(fp);
}
int main() {
int temp1, temp2;
int hang = 30; int lie = 50;
cin >> hang >> lie;
int i, j, k, r = 0, count = 0;
copytext();
//求每行的三升序列
for (i = 0; i < hang; i++)
for (j = 0; j < lie; j++)
for (k = j + 1; k < lie; k++)
if (text[i][j] < text[i][k] && text[i][k] < 90)
for (r = k + 1; r < lie; r++)
if (text[i][k] < text[i][r])
count++;
//求每列的三升序列
for (i = 0; i < lie; i++)
for (j = 0; j < hang; j++)
for (k = j + 1; k < hang; k++)
if (text[j][i] < text[k][i] && text[k][i] < 90)
for (r = k + 1; r < hang; r++)
if (text[k][i] < text[r][i])
count++;
//求左下到右上对角线的三升序列
for (i = 2; i < hang; i++)
for (j = 0; j < lie; j++) {
k = j; r = i;
while (r - 1 >= 0 && k + 1 < lie) {
if (text[i][j] < text[r - 1][k + 1] && text[r - 1][k + 1] < 90) {
temp1 = r - 2; temp2 = k + 2;
while (temp1 >= 0 && temp2 < lie) {
if (text[r - 1][k + 1] < text[temp1][temp2])
count++;
temp1--; temp2++;
}
}
k++; r--;
}
}
//求右上到左下对角线的三升序列
for (i = 0; i < hang; i++)
for (j = 2; j < lie; j++) {
k = j; r = i;
while (k - 1 >= 0 && r + 1 < hang) {
if (text[i][j] < text[r + 1][k - 1] && text[r + 1][k - 1] < 90) {
temp1 = r + 2; temp2 = k - 2;
while (temp2 >= 0 && temp1 < hang) {
if (text[r + 1][k - 1] < text[temp1][temp2])
count++;
temp2--; temp1++;
}
}
k--; r++;
}
}
//求左上到右下对角线的三升序列
for (i = 0; i < hang; i++)
for (j = 0; j < lie; j++) {
k = j; r = i;
while (r + 1 < hang && k + 1 < lie) {
if (text[i][j] < text[r + 1][k + 1] && text[r + 1][k + 1] < 90) {
temp1 = r + 2; temp2 = k + 2;
while (temp1 < hang && temp2 < lie) {
if (text[r + 1][k + 1] < text[temp1][temp2])
count++;
temp1++; temp2++;
}
}
k++; r++;
}
}
cout << count << endl;
return 0;
}
试题 B: 最优旅行
【问题描述】
中国的高铁四通八达,乘坐方便,小明经常乘坐高铁在城市间旅游。
现在,小明又有了一个长假,他打算继续乘坐高铁旅游。这次,他打算到 下面的城市旅游。
上海、广州、长沙、西安、杭州、济南、成都、南京、昆明、郑州、天津、 太原、武汉、重庆、南昌、长春、沈阳、贵阳、福州。
小明打算从北京出发,游览以上每个城市正好一次,最终回到北京。在每 个城市(除北京外),小明都至少停留 24 小时。而当小明决定从一个城市去往 另一个城市时,他只会选择有直接高铁连接的城市,不会在中途换乘转车。
在试题目录下有一个文件 trip.txt 保存了小明可以选择的车次,小明不会 选择其他车次。 小明出发的时间是第 1 天的中午 12:00。
请问,小明游览完以上城市正好一 次,最终回到北京,最快需要多少分钟(请注意单位为分钟)
答案:
// trip.txt
车次 出发站 到达站 出发时间 到达时间
G169 北京 上海 16:40 22:35
G21 北京 上海 19:08 23:40
G18 上海 北京 17:55 22:36
G68 广州 北京 11:13 21:10
G67 北京 广州 12:13 22:19
G1305 上海 广州 15:25 23:38
G86 广州 上海 08:00 14:50
G6122 广州 长沙 21:00 23:36
G6117 长沙 广州 17:55 20:39
G502 长沙 北京 07:36 14:24
G503 北京 长沙 14:41 21:14
G1359 上海 长沙 15:37 20:59
G1348 长沙 上海 09:00 13:41
G362 西安 上海 08:49 14:45
G1936 上海 西安 16:12 22:54
G87 北京 西安 14:00 18:20
G88 西安 北京 13:30 17:55
G98 西安 广州 09:57 17:39
G836 广州 西安 11:24 20:09
G1404 广州 杭州 15:56 23:25
G20 杭州 北京 07:48 12:20
G39 北京 杭州 19:04 23:22
G7355 上海 杭州 21:30 22:28
G7558 杭州 上海 07:06 08:12
G300 济南 上海 06:50 11:40
G333 北京 济南 19:55 21:55
G336 济南 北京 07:45 09:33
G2056 广州 济南 08:05 18:34
G2058 济南 广州 10:14 20:49
G350 成都 北京 07:00 14:46
G89 北京 成都 06:53 14:38
G1888 成都 南京 11:28 22:00
G7180 上海 南京 10:05 11:29
G7003 南京 上海 08:00 09:39
G7613 南京 杭州 16:19 17:40
G7604 杭州 南京 12:09 13:30
G1540 昆明 南京 10:20 21:14
G1539 南京 昆明 09:05 19:40
G2883 成都 昆明 08:51 14:29
G2884 昆明 成都 12:16 17:57
G1538 昆明 郑州 08:46 18:48
G1537 郑州 昆明 10:38 20:49
G2001 郑州 西安 07:52 10:24
G2002 西安 郑州 08:10 10:29
G2231 西安 重庆 17:06 22:56
G2232 重庆 西安 07:05 12:37
G8594 重庆 成都 06:50 08:07
G8599 成都 重庆 22:12 23:29
G1709 天津 重庆 08:05 19:39
G1710 重庆 天津 10:49 22:45
G8901 北京 天津 22:10 22:45
G8928 天津 北京 19:08 19:46
G2609 天津 太原 10:40 14:15
G2610 太原 天津 14:43 18:12
G1954 太原 上海 12:26 21:17
G1952 上海 太原 08:10 17:28
G686 郑州 太原 13:17 17:16
G688 太原 郑州 17:38 21:38
G1864 太原 杭州 12:50 21:10
G1862 杭州 太原 07:14 15:50
G91 北京 太原 08:40 11:07
G92 太原 北京 08:33 11:00
G694 太原 武汉 16:37 22:29
G692 武汉 太原 09:48 16:00
G1722 武汉 上海 08:00 11:53
G1720 上海 武汉 13:51 17:50
G858 西安 武汉 15:18 19:48
G856 武汉 西安 09:17 14:27
G365 天津 武汉 14:56 20:41
G366 武汉 天津 14:30 20:32
G294 长沙 天津 08:47 16:56
G292 天津 长沙 10:58 18:50
G696 长沙 太原 09:23 17:55
G698 太原 长沙 10:46 18:18
G1391 杭州 昆明 11:43 22:53
G1392 昆明 杭州 09:06 20:18
G1514 昆明 南昌 16:00 22:54
G1511 南昌 昆明 08:25 15:38
G1462 南昌 杭州 12:24 15:28
G1451 杭州 南昌 12:30 15:26
G1244 济南 长春 07:42 15:07
G1242 长春 济南 15:33 22:35
G8033 沈阳 长春 06:42 08:40
G1290 长沙 长春 07:21 21:09
G1292 长春 长沙 08:47 22:08
G400 长春 北京 08:32 14:48
G399 北京 长春 15:20 21:45
G1886 南京 成都 08:07 17:54
G579 南京 长沙 09:27 14:10
G580 长沙 南京 15:53 20:40
G1484 贵阳 南京 07:58 18:02
G2335 南京 贵阳 12:07 21:58
G2105 长沙 贵阳 13:17 16:55
G2116 贵阳 长沙 08:11 11:26
G2201 郑州 成都 07:10 13:19
G2212 成都 郑州 16:57 23:04
G1814 上海 郑州 14:15 18:12
G370 郑州 上海 07:33 12:02
G1274 武汉 沈阳 07:23 19:03
G1272 沈阳 武汉 07:32 19:20
G2869 重庆 昆明 07:43 11:55
G2870 昆明 重庆 14:52 19:09
G1335 重庆 上海 08:48 20:56
G1333 上海 重庆 11:39 23:29
G1759 南昌 重庆 07:08 14:45
G1761 重庆 南昌 15:12 22:23
G1493 南京 南昌 13:00 17:21
G1496 南昌 南京 09:04 13:25
G5314 南昌 福州 08:13 11:09
G5312 福州 南昌 18:30 21:25
G1256 长春 上海 11:53 22:54
G1258 上海 长春 09:08 20:05
G1284 沈阳 成都 07:02 21:47
G1282 成都 沈阳 09:06 23:13
G217 北京 沈阳 13:30 17:15
G218 沈阳 北京 08:11 11:58
G2604 沈阳 太原 15:34 23:00
G2602 太原 沈阳 07:44 15:14
G8664 贵阳 成都 19:15 22:35
G8691 成都 贵阳 11:11 14:31
G2958 贵阳 广州 14:03 20:26
G2960 广州 贵阳 07:27 13:43
G1521 武汉 贵阳 08:01 13:25
G1524 贵阳 武汉 14:23 19:33
G1609 福州 广州 08:16 14:15
G1607 广州 福州 14:55 21:05
G1696 昆明 福州 11:11 22:02
G1698 福州 昆明 08:41 19:28
G1636 福州 上海 12:26 16:55
G1631 上海 福州 07:54 12:15
G1642 福州 杭州 14:45 18:32
G1641 杭州 福州 18:55 22:38
答案:
试题 C: 骰子制造
答案:
试题 D: 序列求和
答案:
试题 E: 无方集合
答案:
试题 F: 大胖子走迷宫
题目描述
小明是个大胖子,或者说是个大大胖子,如果说正常人占用 1 × 1 的面积,小明要占用 5 × 5 的面积。
由于小明太胖了,所以他行动起来很不方便。当玩一些游戏时,小明相比小伙伴就吃亏很多。
小明的朋友们制定了一个计划,帮助小明减肥,
计划的主要内容是带小明玩一些游戏,让小明在游戏中运动消耗脂肪,走迷宫是计划中的重要环节。
迷宫可以看成是一个由 n × n
个方阵组成的方阵,正常人每次占用方阵中 1 × 1 的区域,而小明要占用 5 × 5
的区域。
小明的位置定义为小明最正中的一个方格。迷宫四周都有障碍物。
为了方便小明,朋友们把迷宫的 起点
设置在了第 3 行第 3 列,终点
设置在了第 n − 2 行第 n − 2 列。
小明在时刻 0 出发,每单位时间可以向当前位置的上、下、左、右移动单位 1 的距离,也可以停留在原地不动。
小明走迷宫走得很辛苦,如果他在迷宫里面待的时间很长,由于消耗了很多脂肪,他会在时刻 k 变成一个胖子,只占用 3 × 3
的区域。
如果待的时间更长,他会在时刻 2k 变成一个正常人,只占用 1 × 1 的区域。注意,当小明变瘦时迷宫的起点和终点不变。
请问,小明最少多长时间能走到迷宫的终点。注意,小明走到终点时可能变瘦了也可能没有变瘦。
输入格式
输入的第一行包含两个整数 n, k。
接下来 n 行,每行一个由 n 个字符组成的字符串,字符为 + 表示为空地,字符为 * 表示为阻碍物。
输出格式
输出一个整数,表示答案。
样例输入
9 5
+++++++++
+++++++++
+++++++++
+++++++++
+++++++++
***+*****
+++++++++
+++++++++
+++++++++
样例输出
16
数据范围
对于 30% 的评测用例,1 ≤ n ≤ 50。
对于 60% 的评测用例,1 ≤ n ≤ 100。
对于所有评测用例,1 ≤ n ≤ 300,1 ≤ k ≤ 1000。
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct node {
int x, y, time;
};
const int N = 310;
int n, k;
char g[N][N];
bool vis[N][N];
int dr[3] = {2, 1, 0}; // 表示胖子不同时刻的半径
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int bfs() {
queue<node> q;
q.push({3, 3, 0});
vis[3][3] = true;
while (q.size()) {
node t = q.front();
q.pop();
if (t.x == n - 2 && t.y == n - 2) return t.time;
if (t.time / k < 2) q.push({t.x, t.y, t.time + 1}); // 体积为 1 后,就不用原地不动了
for (int i = 0; i < 4; i ++) {
int a = t.x + dx[i], b = t.y + dy[i];
int fat = t.time / k > 2 ? 0 : dr[t.time / k]; // 此时胖子的半径
if (a - fat < 1 || a + fat > n || b - fat < 1 || b + fat > n) continue;
if (vis[a][b]) continue;
bool flag = false; // 判断胖子所占范围内是否有障碍物
for (int j = a - fat; j <= a + fat; j ++)
for (int k = b - fat; k <= b + fat; k ++)
if (g[j][k] == '*') flag = true;
if (flag) continue;
q.push({a, b, t.time + 1});
vis[a][b] = true;
}
}
return -1;
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i ++ ) cin >> g[i] + 1;
cout << bfs() << endl;
return 0;
}
试题 G: 估计人数
【问题描述】
给定一个 N × M 的方格矩阵,矩阵中每个方格标记 0 或者 1 代表这个方格
是不是有人踩过。
已知一个人可能从任意方格开始,之后每一步只能向右或者向下走一格。
走了若干步之后,这个人可以离开矩阵。这个人经过的方格都会被标记为 1,
包括开始和结束的方格。注意开始和结束的方格不需要一定在矩阵边缘。
请你计算至少有多少人在矩阵上走过。
【输入格式】
输入第一行包含两个整数 N、M。
以下 N 行每行包含 M 个整数 (0/1),代表方格矩阵。
【输出格式】
输出一个整数代表答案。
【样例输入】
5 5
00100
11111
00100
11111
00100
【样例输出】
3
【数据规模与约定】
对于所有评测用例,1 ≤ N, M ≤ 20,标记为 1 的方格不超过 200 个。
https://blog.csdn.net/qq_43655831/article/details/115557704
试题 H: 轨道炮
【样例输入】
4
0 0 1 R
0 10 1 R
10 10 2 D
2 3 2 L
【样例输出】
3
【评测用例规模与约定】 对于所有评测用例,
\(1 ≤ N ≤ 1000,−1000000 ≤ X_i , Y_i ≤ 1000000,0 ≤ Vi ≤ 1000000\)。
试题 I: 分考场
【问题背景】
古语有云:春风得意马蹄疾,一日看尽长安花。
当然在一场考试中所有人都春风得意马蹄疾是不可能的,尤其是碰到一些毒瘤出题人的时候。
【问题描述】
又到了每月一次的月考,又是 xf 老师出题。
上一次 xf 老师出的题太毒瘤了,平均分只有 40 多,同学们都非常不满意,毕竟别的科的平均分都是 80 多。
这次 xf 为了不被同学们寄刀片,想了一个办法:只公布所有考场的平均分的平均分。这样他就可以通过调整考场的分配方式,使得平均分显得高。(每个考场都可以容纳无限人)
每次考试也不是所有同学都参加的,只有学号在 [l,r] 这个区间中的同学会参加。
他想知道对于每次考试,他调整过考场后,所有考场的平均分的平均分的最大值。
当然,同学们也可能会努力学习或整日颓废使成绩发生改变。
【输入格式】
输入的第一行包含一个整数 n。
第二行包含 n 个整数,第 i 个数 vi,表示开始时每个同学的成绩。
第三行包含一个整数 q,表示有 q 次操作。
之后 q 行,每行描述一个操作,第一个数表示操作类型。
如果操作为 1 p x,表示学号为 p 的同学分数变为 x。
如果操作为 2 l r k, 表示把学号在 [l,r] 中的同学分成 k 个考场,求这 k 个考场的平均分的平均分的最大值。
【输出格式】
对于每个 2 操作输出一行,四舍五入保留正好 3 位小数。
【样例输入】
5
5 3 4 2 1
5
2 1 4 3
1 4 8
2 3 5 3
1 2 2
2 1 3 2
【样例输出】
3.833
4.333
4.000
【样例说明】
第一个操作询问学号在 [1, 4] 之间的同学分成 3 个考场的平均分的平均分的最大值,最优策略是:{1}, {2, 4}, {3},平均分是
第二个操作把学号为 4 的同学的分数变为 8。
第三个操作询问学号在 [3, 5] 之间的同学分成 3 个考场的平均分的平均分的最大值,最优策略是:{3}, {4}, {5}。
第四个操作把学号为 2 的同学分数变为 2。
第五个操作询问学号在 [1, 3] 之间的同学分成 2 个考场的平均分的平均分的最大值,最优策略是:{1}, {2 3}。
【评测用例规模与约定】
对于全部评测用列,n ≤ 200000, q ≤ 200000, 任意时刻同学的分数 vi ≤ 10^9,k ≤ r − l + 1。
评测时将使用 10 个评测用例测试你的程序,每个评测用例的限制如下:
试题 J: 逃出生天
待补