试题 C: 扩散
本题总分:10 分
【问题描述】
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0 , 0), (2020 , 11), (11 , 14), (2000 , 2000)。
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它
就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色
(如果原来就是黑色,则还是黑色)。
请问,经过 2020 分钟后,画布上有多少个格子是黑色的。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
【解析】
如下图所示,设平面大小为1000010000的方格组成(应注意,1000010000的平面大小在这个题中是够用的)。由于点(0, 0)进行扩展之后会出现负数,所有对这4个点都进行平移,保证其进行2020次扩展之后不会出现负数,下图中只给出了2个点的示意,以红色为起始点,进行了3次扩展之后如下,每一次扩展都是在原来的基础上沿着边缘进行扩展的(同一颜色就是一次进行扩展的点)
【答案】20312088
【程序】
#include <bits/stdc++.h>
using namespace std;
struct node{
int x = 0;
int y = 0;
};
bool arr[10000][10000];
int main()
{
int times = 2020;
int counts = 0;
node temp;
queue<node> que1;//que1中存放用于下一分钟需要进行扩散的点
queue<node> que2;//que2只是用于过渡一下,会将que2中的元素拷贝到que2中
//初始化整个平面,false为白色,true为黑色
for(int i=0; i<10; i++)
for(int j=0; j<10; j++)
arr[i][j] = false;
/* 映射关系如下: */
/* (0, 0) --> (3000, 3000) ; (2020, 11) --> (5020, 3011) */
/* (11, 14) --> (3011, 3014); (2000, 2000) --> (5000, 5000) */
arr[3000][3000] = true;
arr[5020][3011] = true;
arr[3011][3014] = true;
arr[5000][5000] = true;
que1.push({3000, 3000});
que1.push({5020, 3011});
que1.push({3011, 3014});
que1.push({5000, 5000});
for(int i=0; i<times; i++){
while(que1.size()>0){
temp = que1.front();
que1.pop();
//下面4个if用于判断当前这个点是否可以进行上下左右的扩散
//因为如果这个点的隔壁点(上下左右)已经是黑色的点,那么就不能再
//对这个隔壁点进行涂黑。
if(arr[temp.x][temp.y+1] == false) {
que2.push({temp.x, temp.y+1}); //存入下一次用来进行发散的格子坐标
arr[temp.x][temp.y+1] = true;
}
if(arr[temp.x+1][temp.y] == false){
que2.push({temp.x+1, temp.y});
arr[temp.x+1][temp.y] = true;
}
if(arr[temp.x][temp.y-1] == false) {
que2.push({temp.x, temp.y-1});
arr[temp.x][temp.y-1] = true;
}
if(arr[temp.x-1][temp.y] == false){
que2.push({temp.x-1, temp.y});
arr[temp.x-1][temp.y] = true;
}
}
//将que2中的元素复制给que1
while(que2.size()){
que1.push(que2.front());
que2.pop();
}
}
//统计整个平面上有多少个黑点,为便于理解单独统计平面黑点数量,
//其实这个counts++可以直接放在上面while语句中的每个if中的。
for(int i=0; i<10000; i++)
for(int j=0; j<10000; j++)
if(arr[i][j] == true) counts++;
cout << "counts = " << counts << '\n';
return 0;
}
【结果】
yocin@ubuntu:~/Documents/cppPractice$ ./main
counts = 20312088