1191:流感传染
1、题目内容
【题目描述】
有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。
【输入】
第一行一个数字n,n不超过100,表示有n*n的宿舍房间。
接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’表示该房间空着,’@’表示第一天该房间住着得流感的人。
接下来的一行是一个整数m,m不超过100。
【输出】
输出第m天,得流感的人数。
【输入样例】
5
….#
.#.@.
.#@..
#….
…..
4
【输出样例】
16
2、解题思路
看到这个题目,第一时间想到的可能是搜索算法,通过广度优先搜索进行解答,通过bfs确实也可以解决这个问题,但我今天想要讲的是另外一种方法。根据题意,已经得病的人每一天都会对自己的邻居进行一次感染,那么,我们可以找出每一个病人即将感染的所有邻居,将他们进行感染。容易知道,如果一个病人在某一天已经将邻居们都感染,那么接下来的日子里,这个病人去感染的结果是不变的,这个时候我们就不需要再重复让其感染了,而是让新被感染的人去感染他们的邻居,以此类推。这样的思路可能就会更加简单吧。
3、解题代码
#include<stdio.h>
int map[101][101];//用来存放每个房间的情况
int visit[101][101]; //用来标记此病人是否为新被感染的人
int main()
{
char c;
int i,j,k,m,n;
scanf("%d",&n);
for(i=1;i<=n;i++) //将字符转化为数字进行存储会比较方便
{
for(j=1;j<=n;j++)
{
scanf(" %c",&c);
if(c=='.') map[i][j]=1; //健康的人
else if(c=='#') map[i][j]=0; //没有人的空房间
else if(c=='@')
{
map[i][j]=2; //得病的房间
visit[i][j]=1; //初始得病的人
}
}
}
scanf("%d",&m);
m--;//已知第一天的情况要知道第m天的情况,那就需要m-1次的感染过程
while(m--)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(map[i][j]==2&&visit[i][j]==1) //新被感染的人找到周围邻居进行依个感染
{
if(j-1>=1&&map[i][j-1]==1)
{
map[i][j-1]=2;
}
if(j+1<=n&&map[i][j+1]==1)
{
map[i][j+1]=2;
}
if(i-1>=1&&map[i-1][j]==1)
{
map[i-1][j]=2;
}
if(i+1<=n&&map[i+1][j]==1)
{
map[i+1][j]=2;
}
}
}
}
for(i=1;i<=n;i++) //感染完成后,对新感染的人进行标记,便于下一步感染
{
for(j=1;j<=n;j++)
{
if(map[i][j]==2&&visit[i][j]==0)
{
visit[i][j]=1;
}
}
}
}
k=0; //用k去统计第m天的感染人数
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(map[i][j]==2) k++;
}
}
printf("%d",k);
return 0;
}
另外,我在最开始做这道题时也用同样的思路去解题敲代码,可是它虽样例过了但是提交总是错,八成有bug,一直找不出来,希望看我博客的朋友如果知道帮忙指出一下,谢谢,大家相互学习嘛。
#include<stdio.h>
int map[101][101];
int main()
{
char c;
int i,j,k,m,n;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf(" %c",&c);
if(c=='.') map[i][j]=1; //健康的人
else if(c=='#') map[i][j]=0; //没有人的空房间
else if(c=='@') map[i][j]=2; //得病的房间
}
}
scanf("%d",&m);
m--;
while(m--)
{
int visit[101][101]={0};
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(map[i][j]==2&&visit[i][j]==0)
{
visit[i][j]=1;
if(j-1>=1&&map[i][j-1]!=0)
{
map[i][j-1]=2;
visit[i][j-1]=1;
}
if(j+1<=n&&map[i][j+1]!=0)
{
map[i][j+1]=2;
visit[i][j+1]=1;
}
if(i-1>=1&&map[i-1][j]!=0)
{
map[i-1][j]=2;
visit[i-1][j]=1;
}
if(i+1<=n&&map[i+1][j]!=0)
{
map[i+1][j]=2;
visit[i+1][j]=1;
}
}
}
}
}
k=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(map[i][j]==2) k++;
}
}
printf("%d",k);
return 0;
}