问题描述:
包括多组数据。每组数据的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下:
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每组数据中唯一出现一次。
9 6
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
输入
这里使用的dfs方法代码更简洁,但如果数据过多容易栈溢出
import java.util.Objects;
import java.util.Scanner;
public class 红与黑dfs {
static Scanner scanner = new Scanner(System.in);
static int i = scanner.nextInt();
static int j = scanner.nextInt();
static int dx[] = {1, 0, -1, 0};
static int dy[] = {0, 1, 0, -1};
static char map[][] = new char[i][j];
public static void main(String[] args) {
String str;
int x = 0;
int y = 0;
for (int a = 0; a < i; a++) {
str = scanner.next();//输入只能输入string类型,此时为一行的char
for (int b = 0; b < j; b++) {
char cha = str.charAt(b);//用charAt方法将string转为char
map[a][b] = cha;//放入数组中
if (Objects.equals(cha, '@')) {
x = a;
y = b;
}
}
}
System.out.println(dfs(x,y));
for (int a=0;a<i;a++){
for (int b=0;b<j;b++){
System.out.print(map[a][b]);
System.out.print(" ");
}
System.out.println(" ");}
}
public static int dfs(int x,int y){
int res=1;//设置为1,因为原始位置也算一次
map[x][y]='2';//标记已经看过了
for(int a=0;a<4;a++){//for遍历4种位置
int a1=x+dx[a];int b1=y+dy[a];//
if(0<=a1 &&a1<i &&0<=b1&& b1<j&&map[a1][b1]=='.'){
//符合上诉条件,便是可以走的位置
res+=dfs(a1,b1);
//dfs是每次从条路走到黑,直到4个位置都不能走动时
// 便会回溯到上次位置4个位置进行选择
}
}return res;
}
这里使用的是bfs方法
public static int bfs(int x,int y){
LinkedList<int[]> quen=new LinkedList<>();
//bfs需要借助队列的原理进行:先进先出,这里用linkedlist实现
int arry[]={x,y};//需要加入队列的起始位置
quen.addLast(arry);//加入队列
map[x][y]='2';//标记已经用过
int res=1;//原始位置也算一次
while (!quen.isEmpty()){//队列非空就继续,只有在全部可探索位置,都探索后才会为空
int arry1[]= quen.removeFirst();//出队列
if(arry1!=null){
for (int i1=0;i1<4;i1++){
int a1=arry1[0]+dx[i1];
int b1=arry1[1]+dy[i1];//四个位置
if(0<=a1 && a1<i &&0<=b1 && b1<j && map[a1][b1]=='.'){
map[a1][b1]='2';//标记
res+=1;//每次
int arryf[]={a1,b1};
quen.addLast(arryf);//将可探索位置加入队列
}
}
}
}
return res;
}