设某住宿区域是一个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加一,表示统计感染者的数量。