迷宫搜索

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值