Day 19 马踏棋盘(回溯 贪心)

package HorseBoard;

import java.awt.*;
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

public class horseBoardTest {
    private static int x;//棋盘的总行数
    private static int y;//棋盘的总列数
    private static boolean []sign;//记录棋盘的访问情况(即判断位置有没有被走过)
    private static boolean ok;
    public static void main(String[] args) {
        //马踏棋盘
        x = 6;
        y = 6;
        sign = new boolean[x*y];
        int [][]board = new int[x][y];
        Point p = new Point(2,2);
        long time1 = LocalDateTime.now().get(ChronoField.MILLI_OF_DAY);//获取现在是今天的第多少毫秒
        horse(board,p,1);
        long time2 = LocalDateTime.now().get(ChronoField.MILLI_OF_DAY);
        for (int []i:board){
            System.out.println(Arrays.toString(i));
        }
//        System.out.println(time1/1000/60/60);
        System.out.println(time2-time1);
    }
    /*
       board:棋盘
       p:当前要行走的位置的坐标
       temp : 当前走的步数
     */
    public static void horse(int [][]board, Point p,int temp){
        //设置棋盘中当前位置的值为当前步数 并标记当前位置已访问
        board[p.x][p.y] = temp;
        sign[p.x * y + p.y] = true;
        //然后获取下一步可以走的位置
        ArrayList<Point> next = getNext(p);

        //排序
        sort(next);
//        System.out.println(next);
        while (!next.isEmpty()){
            Point nextP = next.remove(0);//取出第一位
            //以取出的位置为原点 继续走
            if (!sign[nextP.x * y + nextP.y]) {//这里一定要判断 否则会出问题!!
                horse(board, nextP, temp + 1);
            }
        }
        //当前原点的所有位置都走过了 那么判断是不是满足条件了
        if (ok){
            return;
        }
        if (temp<x*y&&!ok){
            //如果没有满足条件 那么当前点恢复成未访问 步数也恢复  然后回溯上次栈进行下一步
//            System.out.println(board[p.x][p.y]);
            board[p.x][p.y] = 0;
//            System.out.println(board[p.x][p.y]);
            sign[p.x * y + p.y] = false;
        }else{
            ok = true;
        }

    }
    //对当前位置可走的下一步的位置的集合进行排序 是的当前位置的下一步的下一步的位置越少 越靠前
    public static void sort(ArrayList<Point> p){
        p.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
                int p1 = getNext(o1).size();
                int p2 = getNext(o2).size();
                if (p1<p2){
                    return -1;
                }else if (p1 == p2){
                    return 0;
                }else{
                    return 1;
                }
            }
        });
    }
    //获取下一步可以走的点
    public static ArrayList<Point> getNext(Point p){
        ArrayList<Point> next = new ArrayList<Point>();
        Point temp = new Point();
        if ((temp.x = p.x-2)>=0 && (temp.y = p.y+1)<y){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x-1)>=0 && (temp.y = p.y+2)<y){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x+1)<x && (temp.y = p.y+2)<y){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x+2)<x && (temp.y = p.y+1)<y){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x+2)<x && (temp.y = p.y-1)>=0){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x+1)<x && (temp.y = p.y-2)>=0){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x-1)>=0 && (temp.y = p.y-2)>=0){
                next.add(new Point(temp));
        }
        if ((temp.x = p.x-2)>=0 && (temp.y = p.y-1)>=0){
                next.add(new Point(temp));
        }
        return next;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值