在n*m的棋盘中,马只能走“日” 字。马从位置(x,y)处出发,把棋盘的每一格都走一次,且只走一次。找出所有路径。

×××××××××××××

类似问题:

在半个中国象棋棋盘上,马在左下角(1,1)处,马走日字…而且只能往右走…不能向左…可上可下…求从起点到(m, n)处有几种不同的走法。

八皇后。

×××××××××××××

预备知识---》图的深度优先:

https://www.cnblogs.com/OctoptusLian/p/8260173.html

参考代码1:

https://blog.csdn.net/skylv111/article/details/38930213

参考代码2(优先):

https://blog.csdn.net/qq_35654259/article/details/80644714

参考思考(图例):

https://blog.csdn.net/crayondeng/article/details/17174951

java版本:

https://maozj.iteye.com/blog/671911

***Hanmilton路径 主代码,不需要回到远点的请删除相关部分。8*8的国际象棋棋盘上的一只马,恰好走过除起点外的其他63个位置各一次,最后回到起点,这条路线称为马的一条Hamilton周游路线。对于给定的m*n的国际象棋棋盘,m和n均为大于5的偶数,且|m-n|≤2,试设计一个分治算法找出马的一条Hamilton周游路线。

#include<stdio.h>
#include<stdlib.h>
#define max 101 int m,n;//棋盘大小
int start_x,start_y;//起点位置
int dx[]={-,-,,,-,-,,};
int dy[]={-,-,-,-,,,,};
int board[max][max]={}; int finish(int x,int y)
{//判断是否是死路
if(x< || y< || x>m || y>n || board[x][y]!=)
return ;
else
return ;
}
int next_move(int x,int y)
{//判断下一步能否回到起点
for(int i=;i<;i++)
if(x+dx[i]==start_x && y+dy[i]==start_y)
return ;
return ;
}
void show(int n,int m)
{//输出路线
for(int i=;i<=m;i++) {
for(int j=;j<=n;j++)
printf("%3d",board[i][j]);
printf("\n");
}
}
void move(int x,int y,int num)
{
if(num==n*m && next_move(x,y)) {
show(n,m);
exit();
}
for(int i=;i<;i++) {
int next_x=x+dx[i];
int next_y=y+dy[i];
if(finish(next_x,next_y)) {
board[next_x][next_y]=num+;
move(next_x,next_y,num+);
board[next_x][next_y]=;
}
}
}
int main()
{
printf("请输入棋盘的行数和列数:\n");
scanf("%d%d",&m,&n);
printf("请输入起始坐标:\n");
scanf("%d%d",&start_x,&start_y);
board[start_x][start_y]=;
int number=;
printf("马的周游路线为:\n");
move(start_x,start_y,number);
return ;
}
//辅助理解
#include <stdio.h>
#include <stdlib.h>
#include <iostream> using namespace std; #define max 101 int count = ;
int m,n;//棋盘大小
int start_x,start_y;//起点位置
//考虑到马有8种走法
int dx[]={-,-,,,-,-,,};
int dy[]={-,-,-,-,,,,};
int board[max][max]={}; //输出棋盘
void show(int m,int n){
for(int i = ;i<m;i++){
for(int j = ;j<n;j++){
cout<<board[i][j]<<" ";
}
cout<<endl;
}
}
//判断下一步是否是起始的位置
int next_move(int x,int y){
for(int i = ;i<;i++){
if(board[x+dx[i]][y+dy[i]] == ){//1表示马的起始位置
return ;
}
}
return ;
}
//判断是否填了
int finish(int x,int y){
if(board[x][y] == ){//0表示马没有走过 非0表示马已经走过
return ;
}
return ;
}
//马的下一步走法已经超出棋盘的范围了
int judge(int x,int y,int m,int n){
if(x>=&&x<m&&y>=&&y<n){
return ;
}
return ;
}
//马走的函数
void move(int x,int y,int num){
if(num == m*n+&&next_move(x,y)){
cout<<++count<<endl;
show(m,n);//输出棋盘
cout<<endl;
return ;
}else{
for(int i = ;i<;i++){
if(finish(x+dx[i],y+dy[i])&&judge(x+dx[i],y+dy[i],m,n)){//若不符合上述条件就表示马放弃之后会走这一步了
board[x+dx[i]][y+dy[i]] = num;//在棋盘上记录马的步数
move(x+dx[i],y+dy[i],num+);
board[x+dx[i]][y+dy[i]] = ;//当遍历完棋盘后将棋盘重新置为0(表示马为走过) (不过开始位置还是1这里读者慢慢体会)
}
}
}
} int main(){
cout<<"请输入格子数"<<endl;
cin>>m>>n;
cout<<"请输入起始的位置"<<endl;
cin>>start_x>>start_y;
int number = ;
board[start_x][start_y] = number;//将起始位置为1 move(start_x,start_y,number+);
cout<<count;
}
//上面的如果还理解不了,可以看这个。
#include <stdio.h>
#include <string.h>
int matrix[][];
int journey = ;
int step_x[]={,,,,-,-,-,-},step_y[]={,,-,-,-,-,,}; void outMatrix(){
int i,j;
for (i=;i<;i++)
{
for (j=;j<;j++)
{
printf("%-2d ",matrix[i][j]);
}
printf("\n");
}
} bool outofbounds(int x,int y){
return x < || y < || x >= || y >= ;
} bool isCome(int x,int y){
return matrix[x][y];
} void gotoend(int x, int y ){
if(journey>) return;
int i;
matrix[x][y]=journey++; //当前是第几步
for (i = ;i<;i++)
{
int next_x = x+step_x[i];
int next_y = y+step_y[i];
if(!outofbounds(next_x,next_y) && !matrix[next_x][next_y]){ gotoend(next_x,next_y);
}
}
} int main(){
int start_x,start_y;
int i;
scanf("%d%d",&start_x,&start_y);
for (i = ;i<;i++) {
memset(matrix[i],,sizeof(matrix[]));
}
gotoend(start_x,start_y);
outMatrix();
return ;
}
//这个还有问题
    package test;  

    /**
* create on 2010.05.21 TODO 回溯算法
*
* @author 毛正吉
* @version v1.0
*
*/
public class RecollectionSearch { /**
* @param args
*/
public static void main(String[] args) {
// 注意(0<=x<n && 0<=y<m)
int n = 5;
int m = 4;
int x = 0;
int y = 0;
RecollectionSearch rs = new RecollectionSearch(n, m, x, y);
rs.find(x, y, 2);
System.out.println("######################");
System.out.println("总解数count=" + rs.getCount());
System.out.println("######################"); } // 棋盘行数
private int n;
// 棋盘列数
private int m;
// 马的起始x坐标
private int x;
// 马的起始y坐标
private int y;
// 棋盘坐标
private int[][] a;
// 求解总数
private int count;
// "日"子x坐标
public int[] fx = { 1, 2, 2, 1, -1, -2, -2, -1 };
// "日"子y坐标
public int[] fy = { 2, 1, -1, -2, -2, -1, 1, 2 }; /**
* 构造方法
*
* @param _n
* @param _m
* @param _x
* @param _y
*/
public RecollectionSearch(int _n, int _m, int _x, int _y) {
n = _n;
m = _m;
x = _x;
y = _y;
a = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[i][j] = 0;
}
}
// 马的起点
a[x][y] = 1;
count = 0;
} public void find(int x, int y, int dep) {
int i, xx, yy;
for (i = 0; i < 7; i++) {
xx = x + fx[i];
yy = y + fy[i];
// 判断新坐标是否出界,是否已走过
if (check(xx, yy) == 1) {
a[xx][yy] = dep;
if (dep == n * m) {
output();
} else {
// 从新坐标出发,递归下一层
find(xx, yy, dep + 1);
}
// 回溯,恢复未走标志
a[xx][yy] = 0;
}
}
} /**
* 判断新坐标是否出界,是否已走过
*
* @param xx
* @param yy
* @return
*/
public int check(int xx, int yy) {
if (xx >= n || yy >= m || xx < 0 || yy < 0 || a[xx][yy] != 0) {
return 0;
}
return 1;
} /**
* 输出结果
*/
public void output() {
count++;
System.out.println("count=" + count);
for (int y = 0; y < n; y++) {
System.out.println("");
for (int x = 0; x < m; x++) {
System.out.print(a[y][x] + " ");
}
}
System.out.println("");
} public int getN() {
return n;
} public void setN(int n) {
this.n = n;
} public int getM() {
return m;
} public void setM(int m) {
this.m = m;
} public int getCount() {
return count;
} public void setCount(int count) {
this.count = count;
} public int getX() {
return x;
} public void setX(int x) {
this.x = x;
} public int getY() {
return y;
} public void setY(int y) {
this.y = y;
}
}

【算法】深度优先 马走日 Hamilton routes的更多相关文章

  1. noi 8465 马走日

    8465:马走日 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  1024kB 描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y ...

  2. Problem L: 搜索基础之马走日

    Problem L: 搜索基础之马走日 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 134  Solved: 91[Submit][Status][W ...

  3. 小米 oj 马走日 (bfs 或 双向bfs)

     马走日 序号:#56难度:困难时间限制:1500ms内存限制:10M 描述 在中国象棋中,马只能走日字型.现在给出一个由 N*M 个格子组成的中国象棋棋盘( 有(N+1)*(M+1)个交叉点可以落子 ...

  4. T1219:马走日

    [题目描述] 马在中国象棋以日字形规则移动. 请编写一段程序,给定n×m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. [输入] 第 ...

  5. 马走日的解法(dfs)

    马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. Input 第一行为整数T ...

  6. Knight's Trip---hdu3766(马走日求最小走的步数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3766 给你一个x ,y 求出从(0,0)位置到达需要的最小步数每次只能走日型: 下图为暴力bfs得到的 ...

  7. [openjudge-搜索]深度优先搜索之马走日

    题目描述 描述 马在中国象棋以日字形规则移动.请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入 第一行 ...

  8. NOI2.5 8465:马走日

    描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入 第一行为整数T ...

  9. openjudge8465:马走日 [搜索]

    描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入 第一行为整数T ...

随机推荐

  1. 《前端之路》之二:数据类型转换 && 隐式转换 || 显式转换

    目录 02:数据类型转换 && 隐式转换 || 显式转换 02:数据类型转换 && 隐式转换 || 显式转换 在上一个章节中,我们介绍了 JavaScript 的基本的 ...

  2. ASP.NET Core开发者指南

    ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“ ...

  3. 利用shell脚本生成CHANGELOG.md(包含git提交规范)

    前言 我们经常看到github上面有很多CHANGELOG.MD包含版本的更新信息,如果我们的git提交能遵循一定的规范,那么使用gitlog就能很方便的生成它 生成结果  shell脚本 http ...

  4. 操作MongoDB数据库知识点

    一.命令行操作mongo: 1.开启数据库 mongo 如果启动mongo报以下错误: 运行brew services start mongodb 2.创建数据库并进入实例 use test 3.查看 ...

  5. 论AOP面向切面编程思想

    原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...

  6. 图片与Base64的转换

    图片转为Base64 // 图片转化成base64字符串 public static String GetImageStr() {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 ...

  7. QT5.6.0 VS2013 Win764位系统QT环境搭建过程

    QT5.6.0 VS2013 Win764位系统QT环境搭建过程 没用过QT自己跟同事要了安装包,按照同事指导方法操作安装部署开发环境结果遇到好多问题,错误网上搜遍了所有帖子也没有找到合适的解决方案. ...

  8. 包(package)以及面向对象三个基本特征(继承)的介绍

    1.包(package) 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包也可以看成一个目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维 ...

  9. 在Docker中体验数据库之MySql

    在上一篇在Docker中体验数据库之Mongodb之后,这次记录一下在docker中安装mysql.过程要比Mongodb麻烦一点…… 参考网址: https://dev.mysql.com/doc/ ...

  10. Android远程桌面助手(B1391)

    ARDC(B1391), Download:https://files.cnblogs.com/files/we-hjb/ARDC%28B1391%29_EN.7z Android远程桌面助手(B13 ...