描述
有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。输入
第一行一个数字n,n不超过100,表示有n*n的宿舍房间。 接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’表示该房间空着,’@’表示第一天该房间住着得流感的人。 接下来的一行是一个整数m,m不超过100.
输出
输出第m天,得流感的人数
样例输入
5
….#
.#.@.
.#@..
#…..
….. 4
样例输出
16
爆搜大法好!!!由样例可知,第m天其实只传染了m-1天。所以我们可以直接去bfs,把开始所有的@点加入队列。并把它们的step记为0,当step搜到m时,这意味着已经搜超了一个点。我们就return掉。
代码见下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int maxn=105;
char map[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={0,1,0,-1,0};
int dy[]={0,0,1,0,-1};
struct dqs
{
int x,y,step;
};
int cnt=0,n,m;
bool check(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=n&&map[x][y]!='#'&&!vis[x][y])
return true;
return false;
}
queue<dqs>q;
void bfs()
{
while(!q.empty())
{
dqs head=q.front();
q.pop();
dqs now;
for(int i=1;i<=4;i++)
{
now.x=head.x+dx[i];
now.y=head.y+dy[i];
if(check(now.x,now.y))
{
vis[now.x][now.y]=1;
now.step=head.step+1;
// cout<<now.step<<" now.step "<<head.x<<" head.x "<<head.y<<" head.y "<<now.x<<" now.x "<<now.y<<" now.y "<<endl;
if(now.step==m)
{
printf("%d\n",cnt);
return;
}
cnt++;
q.push(now);
}
}
}
printf("%d",cnt);
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>map[i][j];
if(map[i][j]=='@')
{
cnt++;
dqs begin;
vis[i][j]=1;
begin.x=i;
begin.y=j;
begin.step=0;
q.push(begin);
}
}
scanf("%d",&m);
bfs();
return 0;
}