7-1 感染人数
分数 20
全屏浏览题目
切换布局
作者 黄龙军
单位 绍兴文理学院
设某住宿区域是一个n×n的方阵,方阵中的每个小方格为一个房间,房间里可能住一个人,也可能空着。第一天,某些房间中住着的人得了一种高传染性的流感,以后每一天,得流感的人会使其邻居(住在其上、下、左、右方向存在的房间里面的人)传染上流感,请问:第m天总共有多少人得流感?
输入格式:
第一行输入两个整数n,m(1<n≤20,1≤m≤100),含义如上述;接着输入n行,每行n个字符,表示住宿区域第一天的房间情况,其中,@
表示当天该房间住着得流感的人,.
表示该房间住着健康的人,#
表示该房间是空的。
输出格式:
输出一个整数,表示第m天得了流感的人数。
输入样例1:
5 3
#....
.....
...##
.#.@.
@.#..
输出样例1:
10
输入样例2:
5 4
....#
.#.@.
.#@..
#....
.....
输出样例2:
16
这是一道(char类型)二维数组的遍历问题,再读入的时候先计算一次病人的数量以方便之后再遍历数组的时候不需要在计算一次
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
cin>>a[i][j];
if(a[i][j]=='@')
count++;
}
然后这边再遍历数组(下一天)的时候, 有一个细节的地方,就是再这一行,你遍历到一个病人,那么我们就会把他的上下左右都变成病人,然后count++,然后这时候就会出现一个问题,你把病人的右边设置为病人,那么你下一个遍历的对象就现在病人的右边,那么你又会重新把下一个遍历对象的上下左右又判断一遍,把他们设置成新的病人(红笔标识)
很显然这样是错误的,因为这是下一天才需要干的事情,所以我们需要对当天设置的病人做出标识,让他遍历到他的时候不去判断他,这里我们可以开一个相同大小的二维数组(使用结构体也是OK),初始化为0,然后在设置病人的时候标记为1,新的一天开始又重新初始化为0
while(m--){
memset(b,0,sizeof(b));
for(int i=0;i<n;i++){
for(int j = 0;j<n;j++){
if(a[i][j]=='@'&&!b[i][j])
{
if(i+1<n&&a[i+1][j]=='.') {//i+1<n是为了防止越界,下面同理
a[i+1][j] = '@';
count++;
b[i+1][j] = 1;
}
if(i-1>=0&&a[i-1][j]=='.') {
a[i-1][j] = '@';
count++;
b[i-1][j] = 1;
}
if(j-1>=0&&a[i][j-1]=='.') {
a[i][j-1] = '@';
count++;
b[i][j-1] = 1;
}
if(j+1<n&&a[i][j+1]=='.') {
a[i][j+1] = '@';
count++;
b[i][j+1] = 1;
}
}
全部代码实现:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,count = 0;
cin>>n>>m;
char a[n][n];
int b[n][n];
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
cin>>a[i][j];
if(a[i][j]=='@')
count++;
}
}
m--;
while(m--){
memset(b,0,sizeof(b));
for(int i=0;i<n;i++){
for(int j = 0;j<n;j++){
if(a[i][j]=='@'&&!b[i][j])
{
if(i+1<n&&a[i+1][j]=='.') {
a[i+1][j] = '@';
count++;
b[i+1][j] = 1;
}
if(i-1>=0&&a[i-1][j]=='.') {
a[i-1][j] = '@';
count++;
b[i-1][j] = 1;
}
if(j-1>=0&&a[i][j-1]=='.') {
a[i][j-1] = '@';
count++;
b[i][j-1] = 1;
}
if(j+1<n&&a[i][j+1]=='.') {
a[i][j+1] = '@';
count++;
b[i][j+1] = 1;
}
}
}
}
}
cout<<count;
}