.病毒扩散
一个输入N个数满足n*n,1表示中病毒,0表示健康。每天有病毒的会感染它的上下左右的格子。求共需多少天所有格子全部感染。当输入全0或者全一的话输出-1,否则输出所需天数。
1.首选,分析
第一眼想到的是dfs,但是再想一想,并不是,因为不需要递归往下深钻,只需要看(x,y)结点的上下左右,因此还是打算用暴力分析,二维数组遍历;
2.如何遍历
简单的,就是碰到1,进行逆时针处理:右(x,y+1)下(x+1,y)左(x,y-1)上(x-1,y),判断节点是否为0,为0就置为1,然后一天下来,遍历一遍整个二维数组,找到1的数量,即感染者数量;
但是,有个问题,就是上下左右,数据由0->1的(例如是:(x+1,y)这个人),不能在今天传染其他人,因为是被传染的,若程序遍历到今天被传染的人因该跳过,今天被传染的这个人即使值已经置为1了,也应该跳过,这该怎么办呢?--想到了可以在新增一个二维数据,对应位置上,保留前一天的感染人员状态(即(x+1,y)这个人在此二维数组上还是为0)
3.实现
代码
static class Virus {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int[][] maps = new int[num][num];
int[][] cankao = new int[num][num];
int base = 0;
boolean flag = true;
while (sc.hasNextInt()) {
for (int x = 0; x < num; x++) {
for (int y = 0; y < num; y++) {
int n = sc.nextInt();
maps[x][y] = n;
cankao[x][y] = n;
base = maps[0][0];
if (base != maps[x][y]) {
flag = false;
}
}
}
if (flag) System.out.println(-1);
chuanBo(maps, cankao);
}
}
static void chuanBo(int[][] map, int[][] cankao) {
int total = map.length * map[0].length;
int oneCount = 0; //被感染人数量
int d = 1;
for (; oneCount < total; d++) {
oneCount = 0; //每天重新置为0统计
//iterator map
for (int x = 0; x < map.length; x++) {
for (int y = 0; y < map[0].length; y++) {
if (map[x][y] == 1 && cankao[x][y] == 1) {
//right
if (y + 1 < map[0].length && map[x][y + 1] == 0) {
map[x][y + 1] = 1;
}
//down
if (x + 1 < map.length && map[x + 1][y] == 0) {
map[x + 1][y] = 1;
}
//left
if (y - 1 >= 0 && map[x][y - 1] == 0) {
map[x][y - 1] = 1;
}
//up
if (x - 1 >= 0 && map[x - 1][y] == 0) {
map[x - 1][y] = 1;
}
}
}
}
//每天扫一遍
for (int x = 0; x < map.length; x++) {
for (int y = 0; y < map[0].length; y++) {
if (map[x][y] == 1) {
oneCount++; //每天统计
cankao[x][y] = 1;
}
}
}
}
//output day
System.out.println(d - 1);
}
}
如下: