注解
1、简单模拟。读懂题目意思是关键。
2、输入的第一行是数据组数,下面每组数据分为三部分。第一部分是天数,第二部分是一个长度为16的D数组,第三部分是20乘20的网格。题目意思是,对20乘20的网格的每个点,后一天的细菌数等于当前的细菌数加上D的索引为:当前格子的细菌数加上当前格子的上下左右的细菌数的总和 的细菌数目。且不能大于3,不能小于0。用公式表示更加清晰:
tmp[r][c] = a[r][c] + a[r-1][c] + a[r+1][c] + a[r][c-1] + a[r][c+1];
tmp[r][c] = a[r][c] + D[tmp[r][c]];
tmp[r][c] = min(3, tmp[r][c]);
tmp[r][c] = max(0, tmp[r][c]);
3、注意上下左右,边界条件。(这里有个小trick,我把数组开成了22乘22的数组,也就是在20乘20的外面加了一圈padding,加了一圈0,就可以避免判断如>=0,<20等边界条件了)
4、第一次提交是Presentation Error,后来发现除了最后一组数据,其他组数据结束后都要加个空行!
代码
#include <iostream>
#include <cstring>
using namespace std;
const int ROW = 22;
const int COL = 22;
int main() {
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int D[16];
for(int k=0; k<16; k++) {
cin>>D[k];
}
int a[ROW][COL];
memset(a, 0, sizeof(a));
for(int r=1; r<ROW-1; r++) {
for(int c=1; c<COL-1; c++) {
cin>>a[r][c];
}
}
for(int j=0; j<n; j++) {
int tmp[ROW][COL];
memset(tmp, 0, sizeof(tmp));
for(int r=1; r<ROW-1; r++) {
for(int c=1; c<COL-1; c++) {
tmp[r][c] = a[r][c] + a[r-1][c] + a[r+1][c] + a[r][c-1] + a[r][c+1];
tmp[r][c] = a[r][c] + D[tmp[r][c]];
tmp[r][c] = min(3, tmp[r][c]);
tmp[r][c] = max(0, tmp[r][c]);
}
}
for(int r=0; r<ROW; r++) {
for(int c=0; c<COL; c++) {
a[r][c] = tmp[r][c];
}
}
}
char ans[5] = ".!X#";
for(int r=1; r<ROW-1; r++) {
for(int c=1; c<COL-1; c++) {
cout<<ans[a[r][c]];
}
cout<<endl;
}
if(T){
cout<<endl;
}
}
return 0;
}