问题概述
算法分析
思路很简单,就是一次一次的遍历整个矩阵,遇到0时需要查看上下左右是否有1,如果有,就把0改为1,直到矩阵中不在含有0元素即可。但是有几个细节需要注意。第一点就是可以知道培养皿边缘的格子是特殊的格子,有可能没有上/下/左/右相邻的格子,所以可能需要很多if条件语句来进行判断。第二个方面就是判断是否存在0元素最好有一个标识,在查询0是否存在并且更改0元素的过程后就可以判断。而不需要修改完成后的矩阵再进行遍历,这样会简化工作量。最后,最重要的一点,就是千万不要忘记遍历过程中不能立即修改0元素,否则会影响这一次遍历中其他元素的变化情况。
简化条件判断
针对第一方面采用特殊的填充法。即在L*L矩阵周围填充一圈,形成L+2长,L+2宽的矩阵。并且填充数字为4。这样遍历时从1到L即可,同时免去边界判断。
代码
代码如下(示例):
#include<iostream>
using namespace std;
int main(){
int L,k,n;
cin>>L;
int t=1;
k=0;
n=0;
int p[L+2][L+2];
for(int i=0;i<L+2;i++)
for(int j=0;j<L+2;j++)
p[i][j]=4;
for(int i=1;i<=L;i++){
for(int j=1;j<=L;j++){
cin>>p[i][j];
if(p[i][j]==0) t=0;
}
}
while(!t){
for(int i=1;i<=L;i++){
for(int j=1;j<=L;j++){
if(p[i][j]==0){
if(p[i][j-1]==1||p[i][j+1]==1||p[i-1][j]==1||p[i+1][j]==1)
{ p[i][j]=3; n++;}
}
else n++;
}
}
for(int i=1;i<=L;i++){
for(int j=1;j<=L;j++){
if(p[i][j]==3) p[i][j]=1;
}
}
++k;
if(n==L*L) t=1;
else n=0;
}
cout<<k;
return 0;
}
27ms/ 10908kb。
总结
填充矩阵法。可以减少判断语句,将特殊一般化。