Sicily 1153 马的周游问题

来源:互联网 发布:linux命令用户组密码 编辑:程序博客网 时间:2024/04/28 14:17

1153. 马的周游问题

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge 

Description

和题目C同样的任务,这里只是把棋盘扩大到标准的国际象棋。对这样一个8 * 8的棋盘用同样的方法编号如下:

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       31    32

33    34       35    36       37    38       39    40

41    42       43    44       45    46       47    48

49    50       51    52       53    54       55    56

57    58       59    60       61    62       63    64

Input

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

Output

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

Sample Input

4-1

Sample Output

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

Problem Source

ZSUACM Team Member


一开始实现方法是根据判断出的区域(左上、右上、左下、右下)未访问格子数目,来对下一扩展节点排序,从而减少时间,但是还是超时- -,遂放弃。尝试通过先扩展子节点少的节点来减少时间,成功。

为什么要先扩展子节点少的节点呢?因为这样可以先把没前途的点先走完,因为它没前途,所以从其它点通过它再遍历全图的可能性就太低噜。

#include <iostream>#include <algorithm>#include <list>#include <vector>#include <string.h>using namespace std;// 方便回溯的访问数组int visited[35][35] = {0};// 确定移动方向的增量数组const int moveRow[8] = {2, 1, -1, -2, -2, -1, 1, 2};const int moveCol[8] = {1, 2,  2,  1, -1, -2,-2,-1};// 记录移动路径vector<int> sequence;// 步数纪录int step_count = 0;// 定义一!匹!马!struct horse{int row;int col;int pos;int children_count;};bool valid(int col, int row) {return (col >= 1 && col <= 8) && (row >= 0 && row <= 7);}bool cmp(horse a, horse b) {return a.children_count < b.children_count;}bool dfs(int current) {// 到达64步,说明有解,返回真if(step_count == 64) return true;// 为方便实用增量数组,将编好序号的整数分解为行、列信息vector<horse> validDirections;for(int i = 0; i < 8; i++) {horse tmp;int col = current%8;int row = (int)(((double)current-0.5)/8);// 注意处理最左一行if(col == 0) col = 8;// 每一个马最多有8个方向 tmp.children_count = 0;// 设置下一步走哪里tmp.row = row + moveRow[i];tmp.col = col + moveCol[i];// 如果下一步是有效的if(valid(tmp.col, tmp.row) && visited[tmp.row][tmp.col] == 0) {for(int j = 0; j < 8; j++) {int nextnextRow = tmp.row + moveRow[j];int nextnextCol = tmp.col + moveCol[j];if(valid(nextnextCol, nextnextRow) && visited[nextnextRow][nextnextCol] == 0)tmp.children_count++;}tmp.pos = tmp.row* 8 + tmp.col;validDirections.push_back(tmp);}}sort(validDirections.begin(), validDirections.end(), cmp);for(int k = 0; k < validDirections.size(); k++) {visited[validDirections[k].row][validDirections[k].col] = 1;step_count++;sequence.push_back(validDirections[k].pos);if(dfs(validDirections[k].pos)) return true;// 回溯,将更改过的全局变量全部置为搜索之前的else {visited[validDirections[k].row][validDirections[k].col] = 0;step_count--;sequence.pop_back();}}return false;}int main() {int N;while(cin >> N && N != -1) {memset(visited, 0, sizeof(visited));sequence.clear();step_count = 1;int tmpCol = N % 8;if(tmpCol == 0) tmpCol = 8;visited[(int)((N-0.5)/8)][tmpCol] = 1;sequence.push_back(N);if(dfs(N)) { for(int i = 0; i < sequence.size(); i++) cout << sequence[i] << " ";cout << endl;}}return 0;}




0 0
原创粉丝点击