7-1 感染人数

设某住宿区域是一个n×n的方阵,方阵中的每个小方格为一个房间,房间里可能住一个人,也可能空着。第一天,某些房间中住着的人得了一种高传染性的流感,以后每一天,得流感的人会使其邻居(住在其上、下、左、右方向存在的房间里面的人)传染上流感,请问:第m天总共有多少人得流感?

输入格式:

第一行输入两个整数n,m(1<n≤20,1≤m≤100),含义如上述;接着输入n行,每行n个字符,表示住宿区域第一天的房间情况,其中,@表示当天该房间住着得流感的人,.表示该房间住着健康的人,#表示该房间是空的。

输出格式:

输出一个整数,表示第m天得了流感的人数。

输入样例1:

5 3
#....
.....
...##
.#.@.
@.#..

输出样例1:

10

输入样例2:

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

输出样例2:

16

代码示例: 

#include<iostream>
using namespace std;
int main(){
	int n,m;
	cin>>n>>m;
	char c[n][n];
	cin.get();//将5 3后面的回车给去掉
	for(int i=0;i<n;i++){//输入
		for(int j=0;j<n;j++){
			c[i][j]=cin.get();
		}
		cin.get();//将每行后面的回车给去掉
	}
	for(int k=1;k<m;k++){
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				if(c[i][j]=='@'){
					if(i>0&&c[i-1][j]=='.')c[i-1][j]='*';//上
					if(i<n-1&&c[i+1][j]=='.')c[i+1][j]='*';//下
					if(j>0&&c[i][j-1]=='.')c[i][j-1]='*';//左
					if(j<n-1&&c[i][j+1]=='.')c[i][j+1]='*';//右
                    //要写清楚范围,不然会出现访问下一行的情况
				}//将每一天新感染的人标记为*,避免在访问下一个目标时被上一个目标感染的情况
			}
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				if(c[i][j]=='*')c[i][j]='@';//在一轮后再将*复原成@
			}
		}
	}
	int count=0;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(c[i][j]=='@')count++;//遍历一遍计数
		}
	}
	cout<<count;
}

 易错点分析:

在输入的时候需要注意回车号

在循环中药注意天数,因为是第几天的感染人数,所以需要减一天

使用其他思路要注意避免前一个成员将后一个成员感染后,后一个成员成为新的病原体继续感染的情况,我的代码是使用*来预设感染人员;

需要注意二维数组的下标,因为二维数组在内存中是连续储存的,所以会出现跨行的情况,举个例子:

#include<stdio.h>
int main(){
	int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
	printf("%d",a[0][6]);
}

会出现 7

也就是直接顺序访问第七个元素,所以会出现跨行的情况。

代码思路:

定义一个二维字符数组c[n][n],用于存储矩阵中的每个元素。
使用一个双重循环,从标准输入中读取矩阵中的每个元素,并存储到c[i][j]中,其中i和j分别表示行和列的索引。
使用cin.get();将每行后面的回车符去掉,避免影响后面的输入。
使用一个外层循环,从k=1开始,到k<m结束,每次增加1,表示进行m-1天的感染过程。
在每一天的感染过程中,使用一个双重循环,遍历矩阵中的每个元素,如果该元素是@,表示该位置有感染者,则判断其上下左右四个方向是否有人,如果有,则将其标记为*,表示该人将被感染。
在判断四个方向时,要注意边界条件,即i和j不能超出矩阵的范围。
在一天的感染过程结束后,使用一个双重循环,将矩阵中的所有*复原为@,表示新感染的人已经成为感染者。
在m-1天的感染过程结束后,使用一个双重循环,遍历矩阵中的每个元素,如果该元素是@,表示该位置有感染者,则将一个计数变量count加一,表示统计感染者的数量。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值