sicily1152 非递归版本 与 递归版本

来源:互联网 发布:c语言参考手册第五版 编辑:程序博客网 时间:2024/05/07 13:55

题目

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个整数,从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。


这一题用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是用频繁进行指针合法性检查,而且一旦内存空间不够用了,就会动态开辟空间,然后对原来的数据进行拷贝,这就消耗了大量的时间了。 

原创粉丝点击