Sicily 1152 简单的马周游问题

题目大意

给出5*6的矩阵,求从给定的起点开始,走过且仅一次走过所有的点,最后输出走过的点的序列。


解题思路——采用DFS(深度优先)遍历所有的点。

数据结构:

  • int path[30]:存放马周游的路径
  • int visited[31]:记录一个点是否已经被遍历且放入path
  • Position结构体:记录在矩阵中的某个点的行下标和列下标。
  • dir[8]:马走“日”八个方向对下标的改变。

DFS思想的重点:

  1. 循环结束条件:所有的点全部遍历,存放入path的最终有30个点。
  2. 打印序列的时机:在循环结束时就打印,否则递归返回后会对path有改变,最终输出的结果不符合要求。
遇到的奇葩问题:
  1. 如果visited结构定义为布尔型,则在程序运行过程中,会出现差错。即使未符合循环结束条件时,finished也为真。无法理解~探究中
详细代码如下:

#include<iostream>
#include<memory.h>
using namespace std;

struct Position
{
	int x;
	int y;
	Position(int _x, int _y){
		x = _x; y = _y;
	}
};

int path[30];
int visited[31];
Position dir[8] = {Position(1,-2),Position(2,-1),Position(2,1),Position(1,2),Position(-1,2),Position(-2,1),Position(-2,-1),Position(-1,-2)};
int finished = 0;

Position getPos(int n)
{
	return Position((n-1)/6,(n%6)-1);
}

int getN(Position pos)
{
	return pos.x*6+1+pos.y;
}

void dfs(int count, Position now)
{
	int i,j;
	Position next(0,0);

	if(finished == 1){
		//cout << "finished: " << "第" <<count <<"步:走"<< getN(now) << endl;
		return;
	}
	if(count == 30){
		//cout << "set finished true at " << "第" <<count <<"步:走"<< getN(now) << endl;
		finished=1;
		for(i=0; i<29; i++){
				cout << path[i] << " ";
		}
		cout << path[i] << endl;		
	}

	else{
		for(j=0; j<8; j++){
			next.x = now.x + dir[j].x;
			next.y = now.y + dir[j].y;
			//if(getN(next) == 4)
			//	cout << "又回到了起点" <<endl;
			if(next.x>=0 && next.x<=4 && next.y>=0 && next.y<=5 && visited[getN(next)]== 0){
					path[count] = getN(next);
					visited[getN(next)] = 1;
					count++;
					dfs(count, next);
					visited[getN(next)] = 0;
					count--;
			}
		}
	}
}



int main()
{
	int n,count;

	while(cin>>n && n!=-1){
		memset(path, 0, sizeof(path));
		memset(visited,0,sizeof(visited));
		count = 1;
		finished = 0;
		path[0] = n;
		visited[n] = 1;

		dfs(count,getPos(n));
		
		/*for(int i=0; i<29; i++){
				cout << path[i] << " ";
		}
		cout << path[i] << endl;*/

	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值