1191:流感传染

题目来源:递推算法

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42987451/article/details/82081673