1191:流感传染

题目链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1191

此题做题思路:这个题考查模拟矩阵的搜索过程。用字符二维数组存放网格状的宿舍区,用

int next[4][4]={{0,1},{1,0},{-1,0},{0,-1}};

来模拟感染四个方向。于是大概5m后出现如下代码:

#include<iostream>
using namespace std;
char a[101][101];
int n, m, cnt=0;
int next[4][4]={{0,1},{1,0},{-1,0},{0,-1}};//四个方向感染
void gr(int x, int y)//该函数为感染函数
{
    int dx, dy;
    for(int i=0; i<4; i++)//依次对上下左右进行判断
    {
        dx=x+next[i][0];
        dy=y+next[i][1];
        if(dx>0 && dx<=n && dy>0 && dy<=n && a[dx][dy]=='.')//如果没有越界,并且当前住着没有被感染的病人
        {
            a[dx][dy]='@';//符合上述条件感染
            cnt++;//感染数加1
        }        
    }
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            cin>>a[i][j];
        }        
    cin>>m;
    for(int k=2; k<=m; k++)
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(a[i][j]=='@')gr(i,j);//如果当前为@调用gr()函数
            }
                
    }            
    cout<<cnt<<endl;
    return 0;
}

结果运行如下:

样例显然不对,发生了什么事情?为了查出错误在什么地方,在第37行之后增加如下代码

1     for(int i=1; i<=n; i++)
2     {
3         for(int j=1; j<=n; j++)
4                 cout<<a[i][j]<<" ";
5                 cout<<endl;
6     }

并且输入m=2表示观察一下经过第二天感染后病毒人数是多少,发现感染数显然不对,原因是使用双重循环遍历房间时,如调用gr函数去感染第i行时,其实第i+1行也被感染,再去感染第i+1行时就包含了同一天已被感染的人。所以我这儿用另外一个数组aa[][]将当前感染立马存储,便 有了如下代码:

 1 #include<iostream>
 2 using namespace std;
 3 char a[101][101], aa[101][101];//a数组用于存放上一天的感染情况,aa数组用于存放当天被感染情况。
 4 int n, m, cnt=0;
 5 int next[4][4]={{0,1},{1,0},{-1,0},{0,-1}};
 6 void gr(int x, int y)
 7 {
 8     int dx, dy;
 9     for(int i=0; i<4; i++)
10     {
11         dx=x+next[i][0];
12         dy=y+next[i][1];
13         if(dx>0 && dx<=n && dy>0 && dy<=n && a[dx][dy]=='.')//注意这里是判断a数组
14         {
15             aa[dx][dy]='@';//注意这里是aa数组
16         }        
17     }
18 }
19 int main()
20 {
21     cin>>n;
22     for(int i=1; i<=n; i++)
23         for(int j=1; j<=n; j++)
24         {
25             cin>>a[i][j];
26             aa[i][j]=a[i][j];
27         }        
28     cin>>m;
29     for(int k=2; k<=m; k++)
30     {
31         for(int i=1; i<=n; i++)
32             for(int j=1; j<=n; j++)
33             {
34                 if(a[i][j]=='@')gr(i,j);//这里是根据前一天病毒感染情况来进行感染
35             }
36         for(int i=1; i<=n; i++)//把当天感染结果再赋值给了a数组
37             for(int j=1; j<=n; j++)    
38                 a[i][j]=aa[i][j];
39                 
40     }
41     for(int i=1; i<=n; i++)
42         for(int j=1; j<=n; j++)
43             if(a[i][j]=='@')cnt++;
44             
45     cout<<cnt<<endl;
46     return 0;
47 }

代码是长了点,但还是容易理解的!这个题关键是搞清楚数组存储已被感染和待被感染,以及他们之间的关系,其实还是包含最简单的递推思想的!

转载于:https://www.cnblogs.com/tflsnoi/p/9560726.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值