第十一届蓝桥杯国赛C语言组B类B题扩散
其实我参加的Python组23333,不过把C语言组的题也看了看。
题目
【题目描述】
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)。
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 2020 分钟后,画布上有多少个格子是黑色的。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
初版题解(BFS跑了1个半小时,近2个小时吧。)
碎碎念
这个题真的,感觉他就在诱导我往BFS去想。。然后我一跑就难受了。不过大致算算4个小时内能跑完,我就让他接着跑了。(虽然是赛后补题,也要遵守时间嘛23333)
答案: 20312088
代码
#include<bits/stdc++.h>
using namespace std;
int a[7000][7000], a_[7000][7000];
int xx[4] = {0, 0, -1, 1}, yy[4] = {-1, 1, 0, 0};
struct point{
int x, y, t;
};
void bfs (int x, int y, int _) {
queue<point> q;
q.push(point{x, y, 0});
while (! q.empty()) {
point p = q.front(); q.pop();
cout << p.t <<endl;
for (int i = 0; i < 4; ++ i) {
int tx = p.x + xx[i], ty = p.y + yy[i], tt = p.t + 1;
if(tt > 2020 || a_[tx][ty] == _) continue; // 时间超了或者扩散过了都不能再次通过。
a_[tx][ty] = _;
q.push(point{tx, ty, tt});
}
}
}
int main () {
memset(a_, 0, sizeof(a_));
int x[4] = {0, 2020, 11, 2000};
int y[4] = {0, 11, 14, 2000};
for (int i = 0; i < 4; ++ i) {
cout << i << endl;
// 给所有的点都x轴和y轴各加2040就可以不出界并且不出现负数了。
// 最后一个参数代表这是第几个点产生的影响。这个参数不同可以保证各个点的扩散不相互影响。
bfs(x[i] + 2040, y[i] + 2040, i + 1);
}
int s = 0;
for (int i = 0; i < 7000; ++ i) {
for (int j = 0; j < 7000; ++ j) {
if (a_[i][j]) ++s;
}
}
cout<<s<<endl;// 20312088
return 0;
}
想法挺丰富,运行缺不尽人意。(不过最后确实跑出正确结果了就是了!)
题解(感谢滑稽大佬提醒我可以根据曼哈顿距离来做)
碎碎念
真的绝了,秒出结果!!代码还少!!!
答案: 20312088
代码
#include<bits/stdc++.h>
using namespace std;
int main () {
int x[4]= {0,2020,11,2000};
int y[4]= {0,11, 14,2000};
int s =0;
// 只要遍历下地图,如果某个点到开始的4个点中的一个
// 的曼哈顿距离小于等于2020,就代表可以扩散到。
// 注意数据范围可以写大一点,保证不要有遗漏。
for (int i = -2030; i < 4060; ++ i) {
for (int j = -2030; j < 4060; ++ j) {
for (int k = 0; k < 4; ++ k) {
if (abs(x[k] - i) + abs(y[k] - j) <= 2020){
++ s;
break;
}
}
}
}
cout << s << endl;// 20312088
return 0;
}