sicily 1152. 简单的马周游问题

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

Input

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

Output

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

Sample Input

4-1

Sample Output

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

题目分析

深搜问题,要想加快搜索收敛,将现在可达的位置按照其下一步可达位置的数量排序,
先走可能性最少的路径,从而减少回溯的时间(参考1153,修改相应参数)
这里用普通的深搜也是可以做到的,不要用栈来存储路径,好像就是push和pop操作占了时间,
其实开一个30维的数组就够用了的


#include <stdio.h>
#include <memory.h>

#define ROW 5
#define COL 6
#define ALL 30

int path[ALL];
int count;
int visited[ROW][COL];
int dir[8][2] = {{-2,-1},{-1,-2},{1,-2},{2,-1}, {2,1},{1,2},{-1,2},{-2,1}};
bool doit;

void travel(int r, int c) {
  for (int i = 0; i < 8; ++i) {
    if (doit)
      return;
    int newr = r + dir[i][0];
    int newc = c + dir[i][1];
    if (newr >= 0 && newr < ROW && newc >= 0 && newc < COL && !visited[newr][newc]) {
      visited[newr][newc] = true;
      path[count++] = newr*COL + newc + 1;
      if (count == ALL) {
        doit = true;
        return;
      }
      travel(newr, newc);
      count--;
      visited[newr][newc] = false;
    }
  }
}

int main()
{
  int num;
  while (scanf("%d", &num)) {
    if (num == -1)
      break;
    memset(visited, 0, sizeof(visited));
    doit = false;
    count = 0;
    path[count++] = num;
    visited[(num-1)/6][(num-1)%6] = true;
    travel((num-1)/6, (num-1)%6);

    for (int i = 0; i < ALL; ++i)
      if (i == ALL-1)
        printf("%d\n", path[i]);
      else
        printf("%d ", path[i]);
  }
}

你可能感兴趣的:(sicily 1152. 简单的马周游问题)