题目描述
在边长为9的正方形培养皿中,正中心位置有m个细菌。假设细菌的寿命仅一天,但每天可繁殖10个后代,而且这10个后代,有两个分布在原来的单元格中,其余的均匀分布在其四周相邻的八个单元格中。求经过n(1≤n≤4)天后,细菌在培养皿中的分布情况。
关于输入
输入为两个整数,第一个整数m表示中心位置细菌的个数(2≤m≤30),第二个整数n表示经过的天数(1≤m≤4)。
关于输出
输出九行九列整数矩阵,每行的整数之间用空格分隔。整个矩阵代表n天后细菌在培养皿上的分布情况。
例子输入
2 1
例子输出
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 2 2 2 0 0 0
0 0 0 2 4 2 0 0 0
0 0 0 2 2 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
思路
每个细菌向周围八个单元格扩散,如何表示一个坐标周围的八个格子
for [x][y]:
[x-1][y-1], [x-1][y], [x-1][y+1],
[x1][y-1] , [x][y] , [x][y+1] ,
[x+1][y-1], [x+1][y], [x+1][y+1],
本题经过的日期范围小于等于4,因此无需考虑边界问题。但我们是从头遍历,因此还是需要排除中心格在边界的情况,即中心格不能处于边界。
由题意得:
每个中心格,经过一天后,自己增加的数量是昨天的两倍。 称为,繁殖。
每个中心格,经过一天后,会给八个周围格传播等同昨天数目的细菌。 称为传播。
分别计算这两个部分,令每个昨天的数目为
m
m
m
则,每次中心格的个数为 m *= 2
而,每次周围格子的数目为 该格子数目 += m
之后,将两部分加起来,称为一天过后的量。
然后将spread部分归零,以计算新一天传播的量。
参考代码
#include <cstdio>
#include <cstring>
using namespace std;
int main () {
int Breed[9][9]; // 表示每轮在自己格子上繁殖的细菌数量
int Spread[9][9]; //表示每轮向周围传播的细菌数量
int i,j; //两个通用迭代子
int days, bacteria;
memset(Breed, 0, sizeof(Breed)); //给数组初始化为 0 ;
memset(Spread, 0, sizeof(Spread));
scanf("%d %d", &bacteria, &days);
Breed[4][4] = bacteria; //在数组中心初始化细菌个数
for (int d = 1; d<=days;d++) {
for (i=0;i<9;i++){
for (j=0;j<9;j++){
if ( i!=8 && j!=8 ) {
Spread[i-1][j-1] += Breed[i][j]; //(不能直接加给square会造成超限,应该先加给某个新增值,最后再将两个矩阵相加)
Spread[i-1][j] += Breed[i][j];
Spread[i-1][j+1] += Breed[i][j];
Spread[i][j-1] += Breed[i][j];
Spread[i][j+1] += Breed[i][j];
Spread[i+1][j-1] += Breed[i][j];
Spread[i+1][j] += Breed[i][j];
Spread[i+1][j+1] += Breed[i][j];
// 给格子的上下左右加上本体数量的offspring
Breed[i][j] *= 2; //本体乘
} //在边界上的格子不满足上下左右都有其他格子的条件,为防溢出要禁止。
}
}
for (i=0;i<9;i++){
for (j=0;j<9;j++){
Breed[i][j] += Spread[i][j];
}
}
memset(Spread, 0, sizeof(Spread));
}
for (i=0;i<9;i++){
for (j=0;j<9;j++){
printf("%5d", Breed[i][j] );
if (j<8) printf(" ");
else printf("\n");
}
}
return 0;
}
完。