1003. 二哥养细菌
题目描述
二哥不仅种苹果和花生,还养了很多细菌。二哥的细菌培养皿成方格形,边长为L。长期培养后,二哥发现了细菌繁殖的规律:最初每个格子里的细菌及其后代都会独立繁殖,每次繁殖都会在其上下左右四个相邻的格子里产生新的细菌,而已经存在的细菌在培养皿充满细菌之前都不会死亡。另外,有一些格子里可能还有抗生素,细菌在有抗生素的格子里无法繁殖。
二哥于是发明了一个游戏:取一个新的培养皿,在某些格子里放入细菌或抗生素,然后观察细菌不断繁殖直至充满整个培养皿的所有没有抗生素的格子。不过二哥已经对这个游戏厌烦了,他现在只想知道经过多少轮繁殖后,细菌会充满整个培养皿(不算有抗生素的格子)。
输入格式
第1行有1个整数,边长L。
第2行至第L+1行,每行有L个整数,取值为0、1或2。0表示格子里最初没有细菌,1表示格子里最初有细菌,2表示格子里最初有抗生素。
输出格式
输出一个整数m,表示经过m轮繁殖后,细菌会充满整个培养皿(不算有抗生素的格子)。
说明
【样例解释】 第一轮繁殖:
2 1 0
1 1 1
0 1 0
第二轮繁殖:
2 1 1
1 1 1
1 1 1
【数据范围】
对于全部数据:1≤L≤100 ,保证最终能够充满培养皿(不算有抗生素的格子)。
Sample Input
3
2 0 0
0 1 0
0 0 0
Sample Output
2
这道题很明显你可以通过每一次遍历来得到答案,但是这是一种效率和低下的办法,需要n*L^2次,但是如果一个人在作者道题去模拟这道题时,绝对不是每次遍历,而是记住了上一次由0变为1的位置,所以我们也必须记住位置,这样的效率最高,为L^2次。
下面是源代码
import java.util.ArrayList; import java.util.Scanner; public class Main{ private static Scanner in; public static void main(String[] args) { in = new Scanner(System.in); int L = in.nextInt(); Tag [][] tag=new Tag[L+2][L+2]; ArrayList <Tag> list =new ArrayList<Tag>(); for(int i=0;i<L+2;i++){ for(int j=0;j<L+2;j++){ tag[i][j]=new Tag(); if(i==0||i==L+1||j==0||j==L+1){ tag[i][j].x=i; tag[i][j].y=j; tag[i][j].flag=true; }else{ tag[i][j].x=i; tag[i][j].y=j; tag[i][j].s=in.nextInt(); if(tag[i][j].s==1){ list.add(tag[i][j]); tag[i][j].flag=true; } if(tag[i][j].s==2){ tag[i][j].flag=true; } } } } int a=list.size(); int res=0; int count =0; for(int i=0;i<list.size();i++){ count++; Tag temp = list.get(i); if(!tag[temp.x-1][temp.y].flag){ list.add(tag[temp.x-1][temp.y]); tag[temp.x-1][temp.y].flag=true; } if(!tag[temp.x][temp.y-1].flag){ list.add(tag[temp.x][temp.y-1]); tag[temp.x][temp.y-1].flag=true; } if(!tag[temp.x][temp.y+1].flag){ list.add(tag[temp.x][temp.y+1]); tag[temp.x][temp.y+1].flag=true; } if(!tag[temp.x+1][temp.y].flag){ list.add(tag[temp.x+1][temp.y]); tag[temp.x+1][temp.y].flag=true; } list.remove(i); i--; if(count==a){ a=list.size(); res++; count=0; } } System.out.println(res-1); } static class Tag{ int x; int y; int s; boolean flag; } }