【题目描述】
有一批易感人群住在网格状的宿舍区内,宿舍区为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;
}
#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;
}
其实这个题比较水,只要注意细节就行了