• 1191流感传染数据更新周期问题数据也需要等待


    
    
    【引言】
        数据也需要等待,因为有些数据是存在生命周期的,错了位,那当然就是错了
    【问题的出现】

      C++一本通在线测评"1191:流感传染",题目要求如下

    【题目描述】
    有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,

    以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。 【输入】 第一行一个数字n,n不超过100,表示有n
    *n的宿舍房间。 接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’表示该房间空着,’@’表示第一天该房间住着得流感的人。 接下来的一行是一个整数m,m不超过100。 【输出】 输出第m天,得流感的人数。
    【题目分析】

      这个题目其实很简单的,就是遍历数组,如果某个房间里住着得流感的人,就去查看其邻居是否有人,有则让人得上流感(可以不考虑是否己是流感患者),于是得到如下代码

    //1191:流感传染
    #include<iostream>
    using namespace std;
    char a[102][102];
    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;
        for(int i=2;i<=m;i++)//每天更新人群状态 
            for(int j=1;j<=n;j++)//遍历整个数组 
                for(int k=1;k<=n;k++)
                {
                    if(a[j][k]=='@')//如果当前房间里有患流感的人
                    {
                        if(a[j-1][k]=='.')a[j-1][k]='@';//邻居若有人,则让其患上流感 
                        if(a[j+1][k]=='.')a[j+1][k]='@';
                        if(a[j][k-1]=='.')a[j][k-1]='@';
                        if(a[j][k+1]=='.')a[j][k+1]='@';
                     } 
                 }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) 
                if(a[i][j]=='@')ans++;
        cout<<ans;
        return 0;
    }
    【初次表现】

      程序运行,输入样例数据,

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

      结果显示18(正确结果16)

    【错因分析】

      细细分析出错原因在哪里?--数据生命周期错了.在第一天中,患流感的人只有a[2][4]和a[3][3],a[3][4]是没有患流感的,也就意味着在第二天a[3][5]和a[4][4]应该还是健康的,也就是说a[3][5]和a[4][4]作为流感传染源的生命周期是在第三天开始,但通过上述程序的运行,情况变得不一样了.当j=2,k=4时显然a[2][4]是流感患者,他会让a[3][4]以a[2][5]等四人患上流感,同样在第二天中,当j=2,k=5时,第一天的数据中a[2][5]是健康人,不应该有传染性,但由于上一循环中(j=2,k=4)己把a[2][5]修改为@了,就具有传染性了,这就出错了.同样,a[3][4],a[4][3]也会出现类似错误.

    【解决办法】

      办法一:增加一个维度(天数)--明确划分生命周期,让两天的数据互不干扰.先把前天的数据复制到当前天,再根据前一天的数据更新被传染人员,代码如下

    //1191:流感传染
    #include<iostream>
    using namespace std;
    char a[102][102][102];//第一维度代表天数 
    int n,m,ans;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)cin>>a[1][i][j];
        cin>>m;
        for(int i=2;i<=m;i++)//每天更新人群状态 
        {
            for(int j=1;j<=n;j++)//复制前一天的数据 
                for(int k=1;k<=n;k++)
                    a[i][j][k]=a[i-1][j][k];
                     
            for(int j=1;j<=n;j++)//遍历整个数组 
                for(int k=1;k<=n;k++)
                {
                    if(a[i-1][j][k]=='@')//如果当前房间里有患流感的人
                    {
                        if(a[i-1][j-1][k]=='.')a[i][j-1][k]='@';//邻居若有人,则让其患上流感 
                        if(a[i-1][j+1][k]=='.')a[i][j+1][k]='@';
                        if(a[i-1][j][k-1]=='.')a[i][j][k-1]='@';
                        if(a[i-1][j][k+1]=='.')a[i][j][k+1]='@';
                     } 
                 }        
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) 
                if(a[m][i][j]=='@')ans++;
        cout<<ans;
        return 0;
    }

      办法二:让新感染者数据缓冲一天.新感染者的值不直接换成@,而是换成除.和@,#外的字符,当循环正常读到该天数据时再替换为@,代码如下

    //1191:流感传染
    #include<iostream>
    using namespace std;
    char a[102][102];
    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;
        for(int i=2;i<=m;i++)//每天更新人群状态 
            for(int j=1;j<=n;j++)//遍历整个数组 
                for(int k=1;k<=n;k++)
                {
                    if(a[j][k]=='@')//如果当前房间里有患流感的人,邻居若有人,则让其患上流感 
                    {
                        if(a[j-1][k]=='.')a[j-1][k]='@';//前两行数据己读过了,直接替换不会出错 
                        if(a[j][k-1]=='.')a[j][k-1]='@';
                        if(a[j+1][k]=='.')a[j+1][k]='h';//先标记为感染而不传染 
                        if(a[j][k+1]=='.')a[j][k+1]='h';
                     }
                    if(a[j][k]=='h')a[j][k]='@';//己感染人员标记为感染且可传染 
                 }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) 
                if(a[i][j]=='@')ans++;
        cout<<ans;
        return 0;
    }
    【话题延伸】

      这一现象也正是在背包问题中,0-1背包和完全背包处理方式只是一个顺序就能改变的原因之一.

  • 相关阅读:
    oracle连接数
    python——包
    python——软件开发目录规范
    python——模块介绍
    python——二分法
    python——函数的递归调用
    python08——for 循环
    while循环嵌套练习题
    python07——while循环
    python06入门——流程控制之if判断
  • 原文地址:https://www.cnblogs.com/wendcn/p/15839577.html
Copyright © 2020-2023  润新知