第十一届蓝桥杯国赛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;
} 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值