经典问题:给定一个8×8棋盘,马从任意位置开始,走“日”字,不重复的走完棋盘上的所有位置。

如图所示:

假设从坐标为(2,2)的点开始走,有8个方向可以选择。所以每次都要依据这最多8个方向进行选择。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。在处理马踏棋盘问题时,每次在至多8个可选的方向中,首先通过验证其中一个方向可以成功。贪心算法同样是试探至多的八个可能的出口,但是八个出口的排序并非按照前述的顺时针,而是按照每个可能出口的进一步出口数的递增排序,所以每次先试探的总是进一步出口较少的出口,能够给之后的出口更多的选择,因此贪心算法是比较高效的,而且它不回溯。

package com.bean.knightcruise;import java.util.Scanner;public class KnightCruise2 {/** 马踏棋盘问题:(贪婪法求解) 棋盘有64个位置,“日”字走法,刚好走满整个棋盘* 贪婪的算法则是一步一步依据当前最优的策略,依靠每一步的局部最优,达到最终目标。但是他不一定能够得到最优解。* 关于马踏棋盘的基本过程:国际象棋的棋盘为8*8的方格棋盘。* 现将”马”放在任意指定的方格中,按照”马”走棋的规则将”马”进行移动。* 要求每个方格只能进入一次,最终使得”马”走遍棋盘的64个方格。* 如图所示,任意一个位置,“马”最多有8个方向可以跳动,所以每次都要依据这最多8个方向进行选择。* * 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,* 选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。* 在处理马踏棋盘问题时,每次在至多8个可选的方向中,首先通过验证其中一个方向可以成功。* 贪心算法同样是试探至多的八个可能的出口,但是八个出口的排序并非按照前述的顺时针,* 而是按照每个可能出口的进一步出口数的递增排序,所以每次先试探的总是进一步出口较少的出口,* 能够给之后的出口更多的选择,因此贪心算法是比较高效的,而且它不回溯。*/static final int[] dx = { -2, -1, 1, 2, 2, 1, -1, -2 }; // x方向的增量static final int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 }; // y方向的增量static final int N = 8;static int[][] chessboard = new int[N][N]; // 棋盘/*** *  x,y为棋子的位置*  如果棋子的位置不合法,则返回一个大于8的数。 否则返回棋子的下个出路的个数*/static int wayOut(int x, int y) {int count = 0;int tx, ty, i;// 判断是否超出棋盘边界,该位置是否已经下过if (x < 0 || x > 7 || y < 0 || y > 7 || chessboard[x][y] != 0) {return 9;}for (i = 0; i < N; i++) {tx = x + dx[i];ty = y + dy[i];// 如果棋子的下个出路可行,则出路数自加一次if (tx > -1 && tx < 8 && ty > -1 && ty < 8 && chessboard[tx][ty] == 0)count++;}return count;}/*** 按照棋子的下个出路的个数从低到高排序* 棋子的八个位置的数组*/static void sort(Direction[] next) {int i, j, index;Direction temp = null;// 这里用的选择排序for (i = 0; i < N; i++) {index = i;for (j = i + 1; j < N; j++) {if (next[index].wayOutNum > next[j].wayOutNum)index = j;}if (i != index) {temp = next[i];next[i] = next[index];next[index] = temp;}}}static void move(int x, int y, int step) {int i, j;int tx, ty;// 如果step==64,则说明每个棋格都走到了,现在只需要打印结果就完了if (step == N * N) {for (i = 0; i < N; i++) {for (j = 0; j < N; j++) {System.out.printf("%3d", chessboard[i][j]);}System.out.println();}System.exit(0);}// 下一个棋子的N个位置的数组Direction[] next = new Direction[N];for (i = 0; i < N; i++) {Direction temp = new Direction();temp.x = x + dx[i];temp.y = y + dy[i];next[i] = temp;// 循环得到下个棋子N处位置的下个出路的个数next[i].wayOutNum = wayOut(temp.x, temp.y);}// 配合贪婪算法,按下个棋子的下个出路数排序后,next[0]就是下个出路数最少的那个sort(next);for (i = 0; i < N; i++) {tx = next[i].x;ty = next[i].y;chessboard[tx][ty] = step;//递归调用move(tx, ty, step + 1);/** 如果上面Move()往下一步走不通,则回溯到这里 重置chessboard[tx][ty]为0,接着i++,又循环......*/chessboard[tx][ty] = 0;}}public static void main(String[] args) {int i, j;// 初始化棋盘for (i = 0; i < 8; i++) {for (j = 0; j < 8; j++) {chessboard[i][j] = 0;}}System.out.println("请输入马起始位置坐标(0-7):");Scanner sc = new Scanner(System.in);int x = sc.nextInt();int y = sc.nextInt();// 第一步不用比较,赋值第一步chessboard[x][y] = 1;move(x, y, 2);}
}

运行结果:

请输入马起始位置坐标(0-7):
2
2
45 20 3 54 37 22 5 26
2 55 46 21 4 25 38 23
19 44 1 56 53 36 27 6
58 63 52 47 32 39 24 35
43 18 57 62 51 34 7 28
0 59 48 33 40 31 10 13
17 42 61 50 15 12 29 8
60 49 16 41 30 9 14 11

(完)

JAVA代码—算法基础:马走8×8棋盘问题相关推荐

  1. JAVA代码—算法基础:数独问题(Sodoku Puzzles)

    JAVA代码-算法基础:数独问题(Sodoku Puzzles) 数独问题(Sodoku Puzzles) 数独游戏(日语:数独 すうどく)是一种源自18世纪末的瑞士的游戏,后在美国发展.并在日本得以 ...

  2. JAVA代码—算法基础:拨号键盘的字母组合问题

    拨号键盘的字母组合问题 问题描述 给定一个数字串,返回这个数组串所表示的所有可能的字母组合. 数字和字母的映射关系类似于一个手机的拨号键盘,如图所示: 例如:输入数字串"23" 返 ...

  3. JAVA代码—算法基础:切割钢锯条售卖的问题

    切割钢锯条售卖 题目描述:给定一段长度为n英寸的钢条和一个价格表,求切割方案,使销售收益Rn最大. 注:若长度为n英寸的钢条的价格Pn足够大,最优解可能就是完全不需要切割. 长度(i) 1 2 3 4 ...

  4. JAVA代码—算法基础:循环赛日程表

    循环赛日程表 问题描述:设有n=2的K次方个运动员要进行乒乓球循环赛.现在要设计一个满足一下条件的比赛日程表: 每个选手必须与其它n-1个选手各比赛一次: 每个选手一天只能赛一次: 循环赛一共进行n- ...

  5. 烧水壶java代码_JAVA代码—算法基础:水壶分水的问题

    package com.bean.algorithmbasic; public class WaterAndJugProblem { /* * 给你两壶容量的X和Y升.有无限量的水供应.你需要确定它是 ...

  6. 歌咏比赛java代码_JavaEE基础知识

    一.运算符的优先级别 经验:不用记,灵活运用小括号 二.转义字符 转移字符:表示具体特殊意义的字符本身 \" 代表一个双引号 \' 代表一个单引号 \ 代表一个斜杠 \n 代表换行 \t 代 ...

  7. (Java)算法基础6:图/贪心算法(带模板上考场,模板一定滚瓜烂熟解决考场订制)

    图由点集和边集构成. 有向图有箭头如下下图,无向图无箭头如下图 邻接表,如下图,记录ABCD的直接邻居. 这种结构可以表达所有图,比如有权值的图,如下下图 邻接矩阵法:用一个矩阵来表达上图(有向图,无 ...

  8. 判断三角形java代码_java基础编程题之异常处理

    以下是刚开始学习java的基础编程题,每天持续更新java每个知识点的题目,持续练习,不断提高java基本功,培养编程能力.今天的练习的十八题是java的异常处理的使用. 1.检测年龄不能为负数和大于 ...

  9. 20瓶可乐java,【Java】Java初级算法基础 ,可乐瓶数问题

    [Java] 纯文本查看 复制代码/** * 28人买可乐喝,3个可乐瓶盖可以换一瓶可乐, 那么要买多少瓶可乐,够28人喝? 假如是50人,又需要买多少瓶可乐? * */ public class C ...

最新文章

  1. matlab 小波滤波器系数导出函数,小波基函数和滤波系数.ppt
  2. hdfs合并块_hdfs 小文件合并 问题
  3. ubuntu下clion软件连接boost库文件
  4. LeetCode 41. 缺失的第一个正数
  5. linux kset subsystem 3.10内核,Kobject、Kset 和 Subsystem
  6. SQL之Sort的组合查询
  7. tfs 安装mysql.h_如何在centos5或centos7上编译安装tfs rcserver 模块?
  8. 对于计算机专业英语的问题,计算机专业英语的问题
  9. iptables命令结构之匹配扩展
  10. 短信API接口怎么调用
  11. 创客使用Fusion 360 - 草绘
  12. eclipse新建java项目隐藏了bin文件夹,只有src文件夹,解决方法
  13. 碎片化NFT研究报告:COSONFT提高NFT流动性的探索和实践
  14. 打印********的平行四边形
  15. 【Sensors】原始GNSS测量(6)
  16. 卡马克快速平方根倒数
  17. 你不知道的Windows小技巧~~
  18. 2013年中华医院信息网络大会(郑州会议)资料汇总
  19. NASM: Register 寄存器
  20. C语言 对比数组内容的函数

热门文章

  1. 鸟哥的Linux私房菜基础学习篇 第5章的重点探索
  2. MySQL5.7.28_03_一张图片带你进阶MySQL
  3. uniapp 接口封装
  4. 嵌入式Linux C基本知识点总结
  5. PAT 1166 Summit
  6. php跨域header处理
  7. 黑客攻防技术宝典:Web实战篇(第2版)与第1版的区别
  8. 计算机网络考试数据包格式,计算机网络实验 分析ICMP协议数据包格式.doc
  9. mc有无限火力的服务器地址,我的世界花雨庭无限火力怎么玩 花雨庭无限火力玩法教程...
  10. python tkinter实践之制作看视频小软件