[sicily]1152. 简单的马周游问题

本文介绍了一个经典的马周游问题,即在一个5*6的棋盘中,寻找一条使马能够恰好走过所有格子的路径。通过深度优先搜索的回溯算法实现,详细解释了算法流程,并提供了一段完整的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1152. 简单的马周游问题

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

在一个5 * 6的棋盘中的某个位置有一只马,如果它走29步正好经过除起点外的其他位置各一次,这样一种走法则称马的周游路线,试设计一个算法,从给定的起点出发,找出它的一条周游路线。

为了便于表示一个棋盘,我们按照从上到下,从左到右对棋盘的方格编号,如下所示:

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

马的走法是“日”字形路线,例如当马在位置15的时候,它可以到达2471119232628。但是规定马是不能跳出棋盘外的,例如从位置1只能到达914

Input

输入有若干行。每行一个整数N(1<=N<=30),表示马的起点。最后一行用-1表示结束,不用处理。

Output

对输入的每一个起点,求一条周游线路。对应地输出一行,有30个整数,从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。

Sample Input

4
-1

Sample Output

注意:如果起点和输入给定的不同,重复多次经过同一方格或者有的方格没有被经过,都会被认为是错误的。


典型的深度优先搜索的回溯算法题,由于数据量比较小,直接进行搜索也能以 0.45s 左右的时间AC。采用递归写法,直接对八个方向进行搜索,利用color[][] 数组标记已访问过的地方,自定义check 函数判断是否能访问下一地方。代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int color[5][6];
int movex[8] = {-2,-2,-1,-1,1,1,2,2};
int movey[8] = {-1,1,-2,2,-2,2,-1,1}; 
int path[31];
int flag = 0;
bool check(int x, int y)
{
	if( x<0 || x>4 || y<0 || y>5 )
		return false;
	if(color[x][y] == 1)
		return false;		
	return true;
}

void dfs(int x, int y, int index)
{
	color[x][y] = 1;
	path[index] = 6*x + y + 1;

	if(flag==1) 
		return ; 
	if(index == 30)
	{ 
		flag = 1;
		for(int i=1; i<30; i++)
			cout<<path[i]<<" ";
		cout<<path[30]<<endl;
	}
	else
	{
		for(int i=0; i<8; i++)
		{
			if(check(x+movex[i], y+movey[i]))
				dfs(x+movex[i], y+movey[i], index+1); 
		}
		color[x][y] = 0;
}
}

int main()
{ 
	int n;
	while(cin>>n && n!=-1)
	{
		int index = 0;
		memset(color,0, sizeof(color));
		int x = n/6;
		int y = n%6-1;
		if(y<0) y = 5; 
		flag = 0 ;
		dfs(x,y,index+1);
	} 
	//system("pause");
	return 0;	
}                                 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值