简单马周游问题
http://soj.sysu.edu.cn/show_problem.php?pid=1152
思路:深搜
代码:
#include <stdio.h>
#include <string.h>
const int tot = 30;
int dr[] = {-2, -2, -1, +1, +2, +2, +1, -1};
int dc[] = {-1, +1, +2, +2, +1, -1, -2, -2};
void print_route(int route[], int n)
{
printf("%d", route[0]);
for (int i = 1; i < n; i++) {
printf(" %d", route[i]);
}
printf("\n");
return;
}
// curr in cell (row, col)
bool travel(int row, int col, int steps, int route[], bool vis[][6])
{
if (steps == tot) {
print_route(route, steps);
return true;
}
int next_row, next_col;
for (int i = 0; i < 8; i++) {
next_row = row + dr[i]; // next = [1,30]
next_col = col + dc[i];
if (0<=next_row && next_row<=4 && 0<=next_col && next_col<=5 && !vis[next_row][next_col]) {
vis[next_row][next_col] = true;
route[steps] = next_row * 6 + next_col + 1;
if (travel(next_row, next_col, steps + 1, route, vis))
return true;
vis[next_row][next_col] = false;
}
}
return false;
}
int main()
{
int n, row, col;
bool vis[5][6]; // [1,30]
int route[30];
while(scanf("%d", &n) == 1 && n >= 1) {
memset(vis, false, sizeof(vis));
memset(route, 0, sizeof(route));
row = (n - 1) / 6; // next = [1,30]
col = (n - 1) % 6;
vis[row][col] = true;
route[0] = n;
travel(row, col, 1, route, vis);
}
return 0;
}
马的周游问题
http://soj.sysu.edu.cn/show_problem.php?pid=1153
优化:由于棋盘扩大了,想原来那样的深搜将超时。对下一步的选择进行优化:先沿着可行格子较少的邻居进行深搜
代码:
const int tot = 64;
int dr[] = {-2, -2, -1, +1, +2, +2, +1, -1};
int dc[] = {-1, +1, +2, +2, +1, -1, -2, -2};
struct Cell{
int x, y;
int cnt;
};
bool operator <(const Cell& a, const Cell& b) {
return a.cnt > b.cnt;
}
void print_route(int route[], int n)
{
printf("%d", route[0]);
for (int i = 1; i < n; i++) {
printf(" %d", route[i]);
}
printf("\n");
return;
}
// curr in cell (row, col)
bool travel(int row, int col, int steps, int route[], bool vis[][8])
{
if (steps == tot) {
print_route(route, steps);
return true;
}
int r, c, next_row, next_col;
priority_queue<Cell> cells;
Cell temp;
// 搜索可行格并排序
for (int i = 0; i < 8; i++) {
r = row + dr[i];
c = col + dc[i];
if (0<=r && r<=7 && 0<=c && c<=7 && !vis[r][c]) {// 对于某可行邻居:
int cnt = 0;
for (int j = 0; j < 8; j++) {
next_row = r + dr[j];
next_col = c + dc[j];
if (0<=next_row && next_row<=7 && 0<=next_col && next_col<=7 && !vis[next_row][next_col]) {
cnt++;
}
}
temp.x = r;
temp.y = c;
temp.cnt = cnt; //计算该邻居的可行格数目
cells.push(temp);
}
}
while(!cells.empty()) {
temp = cells.top();
cells.pop();
next_row = temp.x; // next = [1,30]
next_col = temp.y;
vis[next_row][next_col] = true;
route[steps] = next_row * 8 + next_col + 1;
if (travel(next_row, next_col, steps + 1, route, vis))
return true;
vis[next_row][next_col] = false;
}
return false;
}
int main()
{
int n, row, col;
bool vis[8][8];
int route[64];
while(scanf("%d", &n) == 1 && n >= 1) {
memset(vis, false, sizeof(vis));
memset(route, 0, sizeof(route));
row = (n - 1) / 8; // next = [1,30]
col = (n - 1) % 8;
vis[row][col] = true;
route[0] = n;
travel(row, col, 1, route, vis);
}
return 0;
}