sicily1152 非递归版本 与 递归版本

该博客介绍了如何在5*6的棋盘上设计算法,使得马走29步恰好经过每个位置一次,称为马的周游路线。通过输入起点,输出周游路径。博客提供了递归和非递归两种解决方案,强调了马行走方向顺序对运行效率的影响,并提出了使用vector数组优化递归版本的思路,以达到快速求解的目的。
摘要由CSDN通过智能技术生成

题目

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 的时候,它可以到达 2 4 7 11 19 23 26 28 。但是规定马是不能跳出棋盘外的,例如从位置 1 只能到达 9 14

Input

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

Output

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


这一题用dfs基本上可以通过,关键是马所走方向的顺序会影响到ac时间。对于马在目前位置可以走到的下一个位置,用一个vector数组保存,避免每次都要计算和判断

这样基本0.04s可以ac。

递归版本

int walk[8][2] = {{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}};
vector<int> walkable[30];
bool visit[30];
bool finish = false;
int route[30];

bool walk_around(int k,int ini_position)
{
	if(k == 30)
	{
		finish = true;
		return true;
	}
	else
	{
		
		for(int i=0;i<walkable[ini_position].size();++i)
		{
			int new_position = walkable[ini_position][i];
			if(!visit[new_position])
			{
				visit[new_position] = true;
				route[k]=(new_position);
				walk_around(++k,new_position);
				if(finish)
					return true;
				--k;
				visit[new_position] = false;
			}
		}

	}

	return false;
}

非递归版本

 
struct Horse
{
	int position;
	int k;

	Horse(int p,int n):position(p),k(n){};
	Horse(){};
};

Horse walk_around_dfs(int ini_position)
{
	Horse start(ini_position,1);
	Horse dfs[500];
	int top = -1;
	dfs[++top]= start;
	
	while(top!=499)
	{
		Horse current = dfs[top--];
		visit[current.position] = true;
		route[current.k-1] = current.position; 
		bool flag = false;

		if(current.k == 30)
			return current;
		else
		{		
			for(int i = 0 ;i<walkable[current.position].size();++i)
			{
				int new_position = walkable[current.position][i];

				if(!visit[new_position])
				{
					Horse new_horse = current;					
					new_horse.position = new_position;
					new_horse.k = current.k+1;
					flag = true;
					dfs[++top]= new_horse;
				}			
			}
			
			
			if(!flag)
			{
				visit[current.position] = false;
				for(int i = current.k-1;i>=dfs[top].k-1;--i)
				{
					visit[route[i]] = false;
				}
			}
				
		}
	}
	return Horse(-1,-1);
}



这里要注意的是由于消除了递归所以ac的时间要比上面那一题少。这里说一个问题,开始时是使用STL中的stack来实现,回溯的结果发现时间大大超出了限制,后来改用的静态数组模拟栈,轻松过了。由于STL中的stack是采用deque实现的。虽说插入删除的时间也是O(1),但是STL中的stack是用频繁进行指针合法性检查,而且一旦内存空间不够用了,就会动态开辟空间,然后对原来的数据进行拷贝,这就消耗了大量的时间了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值