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
注意:如果起点和输入给定的不同,重复多次经过同一方格或者有的方格没有被经过,都会被认为是错
算法分析:
深度优先搜索 回溯
数据结构:
结构体
sicily1152代码
/*
* main.cpp
*
* Created on: 2014年9月24日
*/
#include <iostream>
using namespace std;
struct position {
int x, y;
};
position direction[9] = { { 0, 0 }, { 1, -2 }, { 2, -1 }, { 2, 1 }, { 1, 2 }, {
-1, 2 }, { -2, 1 }, { -2, -1 }, { -1, -2 } };
int pass[6][7];
position start;
int way[31];
int cou = 0;
int total = 0;
bool flag = false;
void search_position(position now) {
position next;
if (flag == true)
return;
<span style="font-family: Arial, Helvetica, sans-serif;"> // 如果达到最大步数设置flag为true 输出结果</span>
if (cou == 30) {
flag = true;
int j = 0;
for (j = 1; j < 30; j++)
cout << way[j] << " ";
cout << way[j] << endl;
} // 如果还没有达到最大步数
else {
// 搜索下一步
for (int i = 1; i <= 8; i++) {
next.x = now.x + direction[i].x;
next.y = now.y + direction[i].y;
// 如果下一步在棋盘中且没有走过
if (next.x >= 1 && next.x <= 5 && next.y >= 1 && next.y <= 6
&& pass[next.x][next.y] == 0) {
// 设置为走过
pass[next.x][next.y] = 1;
cou++;
// 记录走过的数字
way[cou] = (next.x - 1) * 6 + next.y;
// 搜索下一步
search_position(next);
// 如果达到最大步数递归结束返回
if (flag == true)
return;
// 恢复现场
pass[next.x][next.y] = 0;
way[cou] = 0;
cou--;
}
}
}
}
int main() {
int n;
cin >> n;
while (n != -1) {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++)
pass[i][j] = 0;
}
cou = 1;
flag = false;
way[cou] = n;
int a, b;
a = n / 6;
b = n % 6;
if (b != 0) {
start.x = n / 6 + 1;
start.y = n % 6;
} else {
start.x = n / 6;
start.y = 6;
}
pass[start.x][start.y] = 1;
search_position(start);
cin >> n;
}
return 0;
}
sicily1153 代码
<span style="font-size:14px;">/*
* main.cpp
*
* Created on: 2014年9月25日
* Author: xiangxiyun
*/
#include <iostream>
#include <algorithm>
using namespace std;
struct position {
int x, y, next;
};
position direction[9] = { { 0, 0 }, { 1, -2 }, { 2, -1 }, { 2, 1 }, { 1, 2 }, {
-1, 2 }, { -2, 1 }, { -2, -1 }, { -1, -2 } };
int pass[9][9];
position start;
position lis[9];
int way[65];
int cou = 0;
int total = 0;
bool flag = false;
bool cmp(position a, position b) {
return a.next < b.next;
}
int next_next_steps(position now) {
int n = 0;
for (int i = 1; i <= 8; i++) {
position nex;
nex.x = now.x + direction[i].x;
nex.y = now.y + direction[i].y;
if (nex.x >= 1 && nex.x <= 8 && nex.y >= 1 && nex.y <= 8
&& pass[nex.x][nex.y] == 0) {
n++;
}
}
return n;
}
int next_steps(position now) {
int n = 0;
position nex;
for (int i = 1; i <= 8; i++) {
nex.x = now.x + direction[i].x;
nex.y = now.y + direction[i].y;
if (nex.x >= 1 && nex.x <= 8 && nex.y >= 1 && nex.y <= 8
&& pass[nex.x][nex.y] == 0) {
lis[n] = nex;
lis[n].next = next_next_steps(nex);
n++;
}
}
sort(lis, lis + n, cmp);
return n;
}
void search_position(position now) {
position next;
if (cou == 64) {
flag = true;
int j = 0;
for (j = 1; j < 64; j++)
cout << way[j] << " ";
cout << way[j] << endl;
} else {
int k = next_steps(now);
for (int i = 1; i <= k; i++) {
next = lis[i - 1];
pass[next.x][next.y] = 1;
cou++;
way[cou] = (next.x - 1) * 8 + next.y;
search_position(next);
if (flag == true)
return;
pass[next.x][next.y] = 0;
way[cou] = 0;
cou--;
}
}
}
int main() {
int n;
cin >> n;
while (n != -1) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
pass[i][j] = 0;
}
cou = 1;
flag = false;
way[cou] = n;
int a, b;
a = n / 8;
b = n % 8;
if (b != 0) {
start.x = n / 8 + 1;
start.y = n % 8;
} else {
start.x = n / 8;
start.y = 8;
}
pass[start.x][start.y] = 1;
search_position(start);
cin >> n;
}
return 0;
}
</span>