在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. 【大数据安全】Apache Kylin 安全配置(Kerberos)

    1. 概述 本文首先会简单介绍Kylin的安装配置,然后介绍启用Kerberos的CDH集群中如何部署及使用Kylin. Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop/Spa ...

  2. DSAPI实现简单的透明窗体

    代码 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim B As New Bitmap( ...

  3. 数据结构——Java实现链栈

    一.分析 栈是限定仅在表的一端进行插入或删除操作的线性表,对于栈来说,操作端称为栈顶,另一端则称为栈底,栈的修改是按照后进先出的原则进行的,因此又称为后进先出的线性表. 链栈是指采用链式存储结构实现的 ...

  4. Activiti(一) activiti数据库表说明

    activiti介绍: activiti是一个业务流程管理(BPM)框架.它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流程语言框架.开发人员可以通过插件直接绘画出 ...

  5. datatable的部分问题处理(动态定义列头,给某行添加事件,初始显示空数据)

    一.动态定义列头 在ajax中,用datatable再去重新配置列头,当然传回的数据中,要有对应放列头的键值对 我自定义了Mock数据,用于前端自己交互. 其中,rowdata用于存放传回的数据,co ...

  6. DVWA 黑客攻防演练(十一) 存储型 XSS 攻击 Stored Cross Site Scripting

    上一篇文章会介绍了反射型 XSS 攻击.本文主要是通过 dvwa 介绍存储型 XSS 攻击.存储型 XSS 攻击影响范围极大.比如是微博.贴吧之类的,若有注入漏洞,再假如攻击者能用上一篇文章类似的代码 ...

  7. 轻松学习UML之用例图,时序图

    本文主要讲解UML图中的用例图(Use Case Diagram)和时序图(Sequence Diagram)相关内容,如有不足之处,还请指正. 概述 统一建模语言(UML,UnifiedModeli ...

  8. 对css盒模型的理解

    介绍一下标准css的盒子模型?低版本IE的盒子模型有什么不同的? 1.有两种:IE盒子模型(怪异模式).W3c盒子模型(标准模式). 2.盒模型组成:内容(content).内边距(padding). ...

  9. 位运算 leecode.389. 找不同

    //给定两个字符串 s 和 t,它们只包含小写字母. //字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. //请找出在 t 中被添加的字母 char findTheDifferenc ...

  10. sqlsever存储过程配合代理作业自动定时建表

    1.自动建表存储过程 USE [ThreeToOne] GO /****** Object:  StoredProcedure [dbo].[WTO_CreateTable_ScanDoXXX]    ...