可恶啊,明明是一道普通的bfs,但是第一次用java写还是有一些问题:
1.因为在bfs的时候要判断这个岛最终会不会淹没,所以对于这个岛的每一个点都要判断会不会被淹没,当然前提是要一个bool类型的变量flag判断为有一个点不会被淹没就可以给结果加一然后把flag置否了,避免一个岛屿算了多次。在判断的时候需要一个原始的数组,但是我们原始的数组是要拿来当visited数组用不断改变的,所以在输入数据的时候需要复制成两个数组data和graph,data当visited数组,graph不变当原始地图。
然后我想着Arrays里是不是有数组复制的方法,进去看到一个Arrays.copyOf(),结果复制之后发现不对data变了,graph也变了,我还以为这个copyOf不是复制用的,今天复制了一个一维数组试了一下马上就懂了,原来复制二维数组复制的是地址所以会不对,最后改在for循环里复制了。
2.第二个问题就很ex,我的代码已经感觉没有问题了,在练习系统里提交老是只能正确一点点。然后我又没有测试用例只能把题目的那个7*7的测试用例复制下来自己改变,改成了最后有2个岛屿不会淹没的情况,一提交结果怎么TM的答案还是1,只能祭出print打法慢慢看。最后发现 咦~我的bfs怎么只执行了一次明明有两个岛屿,然后我就在main函数里加了个index,想看它有没有把77 49个点给遍历到,结果单单加了这个打印的代码结果居然又正确了。
后来发现,每当我在第一次从题目里复制的用例上直接更改然后按回车时结果都是错误的,必须要把修改后的数据再次复制粘贴一遍然后才能得到正确结果。不知道是什么ex的问题。。。。。。。。🤷♂️
上面第二个问题终于有答案了。bfs只执行一次是因为我不小心把两个岛屿连在一起了;把岛屿改得断开之后为什么结果还是不对呢我就想着打印一下,打印之后又正确了的主要原因是我把用例给重新复制粘贴了一遍,原因如下:
然后在改为正确答案是2的情况下为什么答案还是1呢?灵感来源于我改了代码让它每输入一行就打印一行,然后我把粘贴的代码一贴上去就打印了6行,只剩下第7行的表示结尾的回车符还没有匹配上所以就没有打印,这个时候我惊奇的发现你如果不敲回车,转而去修改上面你输入的绿色数字是可以做到的。但是!但是!你的这些修改都是无效的,它让你输入说明这些绿色数字它都已经读取到了,现在它需要的也是它会读取的只是你在输入框最末尾输入的东西。所以!所以!我先粘贴了实例代码然后再修改然后再在最末尾打回车和没有进行任何修改是一样的,只用重新复制粘贴才会不一样!
那难道是我的逻辑错了吗?可是我手编了一个10*10的,然后又扩大成20*20的结果都没有毛病啊,烦人( •̀ ω •́ )y。
下面是我的java代码:
import java.util.ArrayDeque;
import java.util.Scanner;
public class Main {
static int[][] dir={{-1,0},{0,1},{1,0},{0,-1}};
static int res;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int length=scanner.nextInt();
char[][] data=new char[length][length];
char[][] g=new char[length][length];
scanner.nextLine();
for (int i = 0; i < length; i++) {
String line=scanner.nextLine();
for (int j = 0; j < length; j++) {
data[i][j]=line.charAt(j);
g[i][j]=line.charAt(j);
}
}
// int index=1;
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
// System.out.println(index++);
if (data[i][j]=='#')bfs(i,j,data, g);
}
}
System.out.println(res);
}
private static void bfs(int i, int j, char[][] data,char[][] graph) {
//System.out.println(res+"-->");
data[i][j]='.';
boolean flag=false;
ArrayDeque<Point> queue=new ArrayDeque<>();
queue.add(new Point(i,j));
while (!queue.isEmpty()){
Point temp=queue.remove();
for (int k = 0; k < 4; k++) {
if (data[temp.i+dir[k][0]][temp.j+dir[k][1]]=='#'){
boolean isSafe=true;
data[temp.i+dir[k][0]][temp.j+dir[k][1]]='.';
queue.add(new Point(temp.i+dir[k][0],temp.j+dir[k][1]));
if (!flag){
for (int l = 0; l < 4; l++) {
//System.out.println(graph[temp.i+dir[k][0]+dir[l][0]][temp.j+dir[k][1]+dir[l][1]]=='.');
if (graph[temp.i+dir[k][0]+dir[l][0]][temp.j+dir[k][1]+dir[l][1]]=='.'){
isSafe=false;
break;
}
}
if (isSafe){res++;flag=true;}
}
}
}
}
}
private static class Point {
int i,j;
public Point(int i, int y) {
this.i = i;
this.j = y;
}
}
}