1,深度优先搜索
package 迷宫;
import java.util.Scanner;
public class Sousuo {
static int n,m,q,p,min=99999999;
static int[][] a=new int[51][51];
static int[][] book=new int[51][51];
public static void dfs(int x,int y,int step){
int[][] next={{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0}};//向上走
int tx,ty,k;
if(x==p && y==q){
//更新最小值
if(step<min)
min=step;
return;//注意: 这里的返回很重要
}
//枚举4种走法
for(k=0;k<=3;k++){
//计算下一个点的坐标
tx= x+ next[k][0];
ty=y+next[k][1];
//判断是否越界
if(tx <1 || tx> n || ty<1 || ty>n){
continue;
}
//判断该点是否为障碍物或者已经在路径中
if(a[tx][ty] ==0 && book[tx][ty]==0){
book[tx][ty]=1;//标记这个点已经走过
dfs(tx,ty,step+1);//开始尝试下一个点
book[tx][ty]=0;//尝试结束,取消这个点的标记
}
}
return;
}
public static void main(String[] args){
int i,j,startx,starty;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
//读入迷宫
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
a[i][j]=sc.nextInt();
}
}
//读入起点和终点坐标
startx=sc.nextInt();
starty=sc.nextInt();
p=sc.nextInt();
q=sc.nextInt();
//从起点开始搜索
book[startx][starty]=1;//标记起点已经在路径中,防止重复走
//起点的x坐标,起点的y坐标,初始步数为 0
dfs(startx,starty,0);
System.out.println(min);
}
}
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
输出:
7
2,广度优先搜索
package 迷宫;
import java.util.Scanner;
class note{
int x;//横坐标
int y;//纵坐标
int f;//父亲在队列中的编号
int s;//步数
public note(int x, int y, int f, int s) {
super();
this.x = x;
this.y = y;
this.f = f;
this.s = s;
}
}
public class SousuoUseBFS {
public static void main(String[] args){
note[] que=new note[2501];
int[][] a=new int[51][51];
int[][] book=new int[51][51];
int[][] next={{0,1},//向右走
{0,-1},//向左走
{1,0},//向下走
{-1,0}};//向上走
int head,tail;
int i,j,startx,starty,k,n,m,p,q,tx,ty,flag;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
//读入迷宫
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
a[i][j]=sc.nextInt();
}
}
//读入起点和终点坐标
startx=sc.nextInt();
starty=sc.nextInt();
p=sc.nextInt();
q=sc.nextInt();
head=1;;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
que[tail].f=0;
que[tail].s=0;
tail++;
book[startx][starty]=1;
flag=0;//用来标记是否到达目标,0表示还未到达
while(head<tail){
//枚举4个方向
for(k=0;k<=3;k++){
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
//判断是否越界
if(tx<1 || tx>n || ty<1 || ty>m)
continue;
//判断是否是障碍物或者已经在路径中
if(a[tx][ty]==0 && book[tx][ty]==0){
//吧这个点标记为已经走过
//注意: 宽度搜索每个点只入队一次,所以和深度搜索不同的是,不需要将book数组还原为0
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].f=head;
que[tail].s=que[head].s+1;//步数是父亲的步数+1
tail++;
}
if(tx==p && ty==q){
flag=1;
break;
}
}
if(flag==1)
break;
head++;
}
System.out.println(que[tail-1].s);
}
}
3,(种子填充法)计算所在岛的面积,上下左右连接的陆地均视为同一岛屿。每次需要向上下左右四个方向扩展,当扩展出的点大于0。
package 迷宫;
import java.util.Scanner;
public class 宝岛探险 {
static int n,m,sum;
static int[][] a=new int[51][51];
static int[][] book=new int[51][51];
public static void dfs(int x , int y){
//定义一个方向数组
int[][] next={{0,1},//向右
{1,0},//向下
{0,-1},//向左
{-1,0}};//向上
int k,tx,ty;
//枚举4个方向
for(k=0;k<=3;k++){
tx=x+next[k][0];
ty=y+next[k][1];
//判断是否越界
if(tx<1 ||tx>n || ty<1 || ty>n)
continue;
//判断是否是陆地
if(a[tx][ty]>0 && book[tx][ty]==0){
sum++;
book[tx][ty]=1;//标记这个点已经走过
dfs(tx,ty);//开始尝试下一个点
//不需还原,是因为找到就标记,不需重复去标记。和迷宫的路径不同。
//book[tx][ty]=0;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int i,j,startx,starty;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
startx=sc.nextInt();
starty=sc.nextInt();
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
a[i][j]=sc.nextInt();
}
}
book[startx][starty]=1;
sum=1;
dfs(startx,starty);
System.out.println(sum);
}
}
10 10 6 8
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
输出:
38