ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

更新"太及时"引发的错

2022-01-24 15:36:59  阅读:184  来源: 互联网

标签:int 及时 房间 引发 cin 更新 传染 102 流感


【问题的出现】

  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]应该还是健康的,但通过上述程序的运行,情况变得不一样了.当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背包和完全背包处理方式只是一个顺序就能改变的原因之一.

标签:int,及时,房间,引发,cin,更新,传染,102,流感
来源: https://www.cnblogs.com/wendcn/p/15839577.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有