深搜,但是要每一步都搜索时要依照下一步能走到的格子数从小到大进行搜索,不然会超时
// Problem#: 1152
// Submission#: 3241599
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int board[5][6]; // 棋盘
int path[30]; // 路径最多有30个点
int dir[8][2] = {{-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}}; // 方向
bool valid(int x, int y) { // 判断是否访问过以及是否在棋盘内
return board[x][y] == false && x >= 0 && x < 5 && y >= 0 && y < 6;
}
int numberOfNextMove(int a, int b) { // 判断下一步能到达的格子数
int total = 0;
for (int i = 0; i < 8; i++) {
if (valid(a + dir[i][0], b + dir[i][1])) {
total++;
}
}
return total;
}
struct node {
int x, y, sub;
node() {
x = y = sub = -1;
}
node(int a, int b) {
x = a;
y = b;
sub = numberOfNextMove(a, b);
}
};
node next(node n, int i) { // 下一个格子
return node(n.x + dir[i][0], n.y + dir[i][1]);
}
bool cmp(node a, node b) { // 比较下一步能走到的格子数
return a.sub < b.sub;
}
node num2node(int n) { // 数字变为横纵坐标
if (valid((n - 1) / 6, (n - 1) % 6)) {
return node((n - 1) / 6, (n - 1) % 6);
}
}
int node2num(node n) { // 横纵坐标变为数字
return 6 * n.x + n.y + 1;
}
bool DFS(node cur, int layer) { // 深搜,cur 为当前节点, layer为已走过的格子数
if (layer == 29) { // 都走过了
path[layer] = node2num(cur); // 加入最后一个路径并返回
return true;
}
board[cur.x][cur.y] = true; // 标记当前格子已走过
vector<node> v; // 存储当期格子能走到的格子
path[layer] = node2num(cur);
for (int i = 0; i < 8; i++) {
node n = next(cur, i);
if (valid(n.x, n.y)) {
v.push_back(n);
}
}
sort(v.begin(), v.end(), cmp); // 按照下一步能走到的格子数排序
for (int i = 0; i < v.size(); i++) {
if (DFS(v[i], layer + 1) == true) { // 继续以下一个节点为当前节点,layer+1深搜,如果到达终点就返回
return true;
}
}
board[cur.x][cur.y] = false; // 还原当前节点
return false;
}
int main() {
int n;
while (cin >> n && n != -1) {
node start = num2node(n);
DFS(start, 0);
cout << path[0];
for (int i = 1; i < 30; i++) {
cout << " " << path[i];
}
cout << endl;
memset(board, 0, sizeof(board));
}
}