韩顺平老师的课程马踏棋盘算法优化

1. 应用的知识点java的二维数组;int[][] chessBorad=int [X][Y];
2. 用了一维数组boolean[] visited=new boolean[X*Y];
3. Point p;p.x,p.y,点的坐标的这个类

在一个8*8的方格中,要求从任何的起点出发尽可能多的不重复的方格?怎么可以把方格走完?
在这里插入图片描述
实现思路:
在这里插入图片描述
代码实现:
注意的地方:要实现这个算法需要了解Point类java.awt包中,需要把这个类里面的点存入ArrayList集合中
travelChessBorad();方法用于用合适的点遍历棋盘。
ArrayList next(Point currrentPoint)方法:仅仅表示符合要求的点,然后travelChessBorad()中调用 这个方法就可以实现找出所有的棋盘中符合要求 的点。(后期还会对这个进行优化)

package com.demo.sort;

import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;

class HorseChessBoard {

    private static int X;//棋盘的列
    private static int Y;//棋盘的行
    //    用一个数组来表示这个棋盘的位置是否被访问过
    private static boolean visited[];
    //    使用一个属性来表示棋盘是否所有的位置都被访问
    private static boolean finished;//所有的boolean默认为false
    static int count = 0;//用来统计次数的

    /**
     * @param args
     */


//   这个是一个判断条件的函数如果符合条件就添加进来
    public static void main(String[] args) {

        X = 6;
        Y = 6;
        int row = 1;//马儿的初始位置从1开始
        int column = 1;//马儿的初始位置从1开始编号

        visited=new boolean[X*Y];//初始值都为false
        int[][] chessborad = new int[X][Y];
//      测试一下耗时
        long start = System.currentTimeMillis();
        travelChessBorad(chessborad, 1, 2, 1);
//打印出来毫秒
        long end = System.currentTimeMillis();
        System.out.println((end - start));

//        输出棋盘
        for (int[] rows : chessborad) {
            System.out.println();
            for (int step : rows) {
                System.out.print(step + "\t");

            }
        }

        System.out.println("循环次数"+count);
    }

    //    遍历棋盘用来找符合的情况
    public static void travelChessBorad(int[][] chessborad, int row, int column, int step) {
        //1.走完棋盘
        chessborad[row][column] = step;//把每一个方格当成下一个数字
//        row=4 X=8,column=4
//        visited标记该位置已经被访问
        visited[row * X + column] = true;//表示马儿从该点开始出发

//  获取当前位置可以走的下一个集合    把棋盘传入我们需要的函数,用来判断是否符合条件
        ArrayList<Point> ps = next(new Point(column, row));


//        对他的下一步的次数进行非递减排序
        sort(ps);




//        遍历ps
        while (!ps.isEmpty()) {
            Point p = ps.remove(0);//可以走的位置的值全部为0,走了之后visited[row][column]=true;


//            判断该点是否被访问过
            if (!visited[p.y * X + p.x]) {//说明还没有被访问
//               访问下一个点
                travelChessBorad(chessborad, p.y, p.x, step + 1);
                count++;

            }
        }

//2.没有走完棋盘
//         判断马儿是否完成了任务,使用step和应该步数比较

//        step<X*Y是否走完有两种情况:1.棋盘没有走完 2. 正处在一个回溯的过程

        if (step < X * Y && !finished) {

            chessborad[row][column] = 0;
            visited[row * X + column] = false;
        } else {
            finished = true;
        }


    }



    //当前的这个点由自己来决定,只要符合要求即可。
    public static ArrayList<Point> next(Point currentPoint) {
//        创建一个ArrayList
        ArrayList<Point> ps=new ArrayList<>();
        //创建一个Point
        Point p1 = new Point();
//        表示马儿可以走,图中的数表示最多的马可以走的个数,0,1,2,3,4,5,6,7

//表示马儿可以走5这个位置
//        (总共八个数可以走只要符合稍作就可以加入到这个数组中)
        if ((p1.x = currentPoint.x - 2) >= 0 && (p1.y = currentPoint.y - 1) >= 0) {
            ps.add(new Point(p1));//符合要求把这个点加入到数组中
        }
//        0
        if ((p1.x = currentPoint.x + 2) <X && (p1.y = currentPoint.y - 1) >= 0) {
            ps.add(new Point(p1));//符合要求把这个点加入到数组中
        }

//        表示走6这个位置,如果x,y不出边界就可以
        if ((p1.x = currentPoint.x - 1) >= 0 && (p1.y = currentPoint.y - 2) >= 0) {

            ps.add(new Point(p1));

        }
//        表示走7这个位置
        if ((p1.x = currentPoint.x + 1) < X && (p1.y = currentPoint.y - 2) >= 0) {
            ps.add(new Point(p1));
        }

//        1这个位置

        if ((p1.x = currentPoint.x + 2) < X && (p1.y = currentPoint.y +1) <Y) {
            ps.add(new Point(p1));//符合要求把这个点加入到数组中
        }
//        4

        if ((p1.x = currentPoint.x -2) >=0 && (p1.y = currentPoint.y +1) <Y) {
            ps.add(new Point(p1));//符合要求把这个点加入到数组中
        }

//       3
        if((p1.x=currentPoint.x-1)>=0&&(p1.y=currentPoint.y+2)<Y){
            ps.add(new Point(p1));

        }
//        2
        if((p1.x=currentPoint.x+1)<X &&(p1.y=currentPoint.y+2)<Y){
            ps.add(new Point(p1));

        }


        return ps;//返回这个点



    }


// 减少回溯的次数
//    对这个算法的回溯的时候进行 非递减排序(1,2,2,3,3,4,5,5)可以有重复的数字

    public static void sort(ArrayList<Point> ps){
        ps.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
//                获取o1的下一步的所有的位置个数

                int count1=next(o1).size();
                int count2=next(o2).size();

                if (count1<count2){

                    return -1;
                }else if(count1==count2){

                    return  0;
                }else {
                    return -1;
                }
            }
        });



    }







}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有时间指导毕业设计

觉得写的好的话可以给我打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值