当前位置:   article > 正文

骑士巡游问题_骑士巡游c++递归

骑士巡游c++递归

1、问题描述

在N行N列的棋盘上,一位骑士按象棋中“马走日”的走法从初始坐标位置(Sx,Sy)出发,要求遍历(巡游)棋盘中每一个位置一次,请输出骑士巡游的位置顺序,或输出无解。

2、问题分析

对于这个问题,我们可以用回溯法来处理。设骑士的当前坐标为q(x,y),则它的下一步的坐标可能为:
q(x+2,y+1) —— 右下走“日” (念ri,即竖着走)
q(x+1,y+2) —— 右下走“曰”(念yue,即横着走)
q(x-1,y+2) —— 右上走“曰”
q(x-2,y+1) —— 右上走“日”
q(x-2,y-1) —— 左上走“日”
q(x-1,y-2) —— 左上走“曰”
q(x+1,y-2) —— 左下走“曰”
q(x+2,y-1) —— 左下走“日”

由于骑士总是从坐标q(1,1)出发,因此可将骑士巡游的第一步固定为坐标q(1,1),其下一步由如上所述顺序依次试探,并且设以标记数组,用于标记每次试探的位置,若试探成功,则标记位置置为当前可行步数(即递归函数内的递归层数),若试探失败,则回溯至上一步。反复执行上述步骤,直至可行步数为n×n为止。

3、算法策略与实现源码

设一标记数组int m[n+1] [n+1](为方便计算,数组皆多开一个或一系空间),用于标记每次试探的位置,设一个二维数组next[9] [2]
用于计算下一步的试探坐标,设以整型变量step,用于记录可行步数,设以递归函数tour(int step,int x,int y),其函数返回类型为bool,当step=n×n+1时,表示巡游成功。

#include<iostream>
#include<iomanip> 
using namespace std;
const int n = 5;
int m[n+1][n+1];
int next[9][2] = {{0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
bool tour(int step,int x,int y){
	if(step == n*n + 1)  return true;
	bool q = false;
	for(int k = 1;k <= 8; k++){
		int u = x + next[k][0];
		int v = y + next[k][1];
		if(u >= 1 && u <= n && v >= 1 && v <= n){
			if(!m[u][v]){
			m[u][v] = step;
			q = tour(step + 1,u,v);
			if(!q) m[u][v] = 0;
	    }
		}
	}
	return q;
}
int main(){
	m[1][1] = 1;
	if(tour(2,1,1)){
		for(int i = 1;i <= n; i++){
			for(int j = 1; j <= n; j++)
			cout << setw(4) << m[i][j];
			cout << endl;
		}
	}
	else cout << "no solution" << endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/573590
推荐阅读
相关标签
  

闽ICP备14008679号