1191:流感传染

1191:流感传染

  • 流感传染

    此题是在递推中出现的,但是我没有想到纯递推的做法

    可能BFS也算递推的一种?

题目描述

有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空

着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),

空房间不会传染。请输出第m天得流感的人数。

输入

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

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

得流感的人。

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

输出

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

输入样例

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

输出样例

16

思路

  • BFS,每感染一个,ans++

  • 需要注意的地方是:

    • 邻居指的是 上下左右 四个方向 (我一开始以为八个方向,整了老半天)

    • 图一开始就已经有了第一天感染的人,而且第m天的人数,指的是第m天还没有开始感染的人数

      ​ 一共要循环 m-1 次

代码

#include <bits/stdc++.h>
using namespace std;
int n,em,ans;
char m[110][110];
pair<int,int> t,tt;
queue<pair<int,int> > v,q;
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
int main(){
    cin>>n;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            cin>>m[i][j];
            if(m[i][j]=='@'){
                t.first = i;
                t.second = j;
                v.push(t);//把感染的坐标放入队列中
                ans++;//先统计第一天中的感染人数
            }
        }
    }
    cin>>em;
    for(int i=1;i<em;++i){//循环em-1次
        while(!v.empty()){//因为要记录次数,所以要用两个队列来倒着,v是主要的,q是辅助队列
            t = v.front();
            v.pop();
            for(int i=0;i<4;++i){
                int nx = t.first + xx[i];
                int ny = t.second + yy[i];
                if(nx>=1&&ny>=1&&nx<=n&&ny<=n&&m[nx][ny]=='.'){
                    tt.first = nx;
                    tt.second = ny;
                    q.push(tt);//感染一天,就是把v中的所有元素都出队,然后四个方向感染,合适的入到q
                    ans++;//直接记录人数
                    m[nx][ny] = '@';
                }
            }
        }
        while(!q.empty()){//再把q中的元素导入v中,满足(!v.empty()) 继续BFS
            v.push(q.front());
            q.pop();
        }
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2019-03-17 18:45  南风--  阅读(1107)  评论(1编辑  收藏  举报