第十一届蓝桥杯 扩散 c++

试题 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
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值