一本通1191 流感传染

【题目描述】

有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。

【输入】

第一行一个数字n,n不超过100,表示有n*n的宿舍房间。

接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’表示该房间空着,’@’表示第一天该房间住着得流感的人。

接下来的一行是一个整数m,m不超过100。

【输出】

输出第m天,得流感的人数。

【输入样例】

5
....#
.#.@.
.#@..
#....
.....
4

【输出样例】

16


思路:其实很简单,首先想到的思路肯定是每一天都遍历一遍二维数组,然后把是"@"的上下左右是"."的变成"@",根据m和n的取值范围得:遍历一次二维数组的复杂度在10000以内,而m小于等于100,所以最大的复杂度才只是10000*100是可以在1s内跑出来的


代码:


#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<cstring>
using namespace std;
char a[105][105];//根据n的取值范围开一个二维数组记录整张正方形的图
int n,m,ans;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
     for(int j=1;j<=n;j++)
     cin>>a[i][j];//输入
 }
 cin>>m;//输入第几天
 m--;//这里非常重要,前几次一直不对就是因为这里。题目很细节(kengdie)地说是第m天,也就是第m天还没有开始,也就是只传染了m-1天,所以要-1
 while(m--)
 {
 for(int i=1;i<=n;i++)
 {
  for(int j=1;j<=n;j++)
  {
   if(a[i][j]=='@')//根据思路遍历上下左右。但是后来才发现有个问题。比如说,这个"@",传染到了它下面的一个,但是这个刚刚被传染的是不能去传染别人的,所以在遍历的时候就相当于多传染了一波。所以在这里先不把这个刚刚被传染的字符变成"@",而是变成一个不是题目中提到的三个字符的字符,这样在下面再加一次遍历把它改成"@"即可。但是这样又要重新考虑复杂度,一个循环里多遍历一次,相当于复杂度到了2*10000*100还是可以1s内跑出来(电脑真厉害)
   {
    if(a[i-1][j]=='.')
    a[i-1][j]='!';
    if(a[i+1][j]=='.')
    a[i+1][j]='!';
    if(a[i][j-1]=='.')
    a[i][j-1]='!';
    if(a[i][j+1]=='.')
    a[i][j+1]='!';//比如先都变成"!"
   }
  }
 }
 for(int i=1;i<=n;i++)
 {
  for(int j=1;j<=n;j++)
  {
   if(a[i][j]=='!')
   a[i][j]='@';//再遍历一次把"!"都变成"@"
  }
 }
}
    for(int i=1;i<=n;i++)
    {
     for(int j=1;j<=n;j++)
     {
      if(a[i][j]=='@')
      ans++;//最后再扫一波,看看有几个被感染了
  }
 }
 cout<<ans;
 return 0;
}
 
其实这个题比较水,只要注意细节就行了
posted @ 2020-05-12 16:09  徐明拯  阅读(1495)  评论(0编辑  收藏  举报