Sicily 1152 & 1153 简单的马周游问题
这题做得相当曲折,一开始以为是和8皇后差不多,于是按8皇后解法做,后来发现自己列出所有的路线,错了
修改后,发现超时了,后来改了好几次都超时了, 看了大牛的解题报告,才知道要剪枝
先搜索扩展点最小的点, 因为它的扩展点小,就意味着从其它点到达它的路径很少,先搜索它会提高效率
这是我个人的理解
1152和1153都差不多,只不过1153数据规模比1152数据规模大
1152
#include <iostream>
#include <vector>
#include <memory.h>
#include <algorithm>
using namespace std;
struct point
{
int x;
int y;
int totaltonext;
};
int board[10][10];
int move_x[] = {-1, -1, -2, -2, 1, 1, 2, 2};
int move_y[] = {-2, 2, 1, -1, 2, -2, 1, -1};
int path[30];
bool dfs(point, int);
bool isvalue(point );
bool cmp(point , point );
int main()
{
int n;
point p;
//freopen("C:\\Users\\Haojian\\Desktop\\test.txt", "r", stdin);
while (cin >> n && n != -1)
{
isfind = false;
memset(board, 0, 10*10*sizeof(int));
p.x = (n - 1) / 6 + 1;
p.y = n - ((p.x-1) * 6);
//p.num = 1;
// path[p.num-1] = n;
path[0] = n;
board[p.x][p.y] = 1;
dfs (p, 1);
}
return 0;
}
bool dfs (point p, int current)
{
point n;
if (current == 30)
{
for (int i = 0; i < 29; i++)
cout << path[i] << " ";
cout << path[29];
cout << endl;
return true;
}
else
{
vector<point> tmp;
for (int i = 0; i < 8; i++)
{
n.x = p.x + move_x[i];
n.y = p.y + move_y[i];
n.totaltonext = 0;
if (isvalue(n))
{
point k;
for (int j = 0; j < 8; j++)
{
k.x = n.x + move_x[j];
k.y = n.y + move_y[j];
if (isvalue(k))
n.totaltonext++;
}
tmp.push_back(n);
}
}//计算下一个要找的点的扩展点
sort(tmp.begin(), tmp.end(), cmp);//按扩展点从小到大排序
//从扩展点小的开始搜索
for (int i = 0; i < tmp.size(); i++)
{
board[tmp[i].x][tmp[i].y] = 1;
path[current] = (tmp[i].x - 1) * 6 + tmp[i].y;
if (dfs(tmp[i], current+1)) return true;
board[tmp[i].x][tmp[i].y] = 0;
}
}
return false;
}
bool cmp(point a, point b)
{
return a.totaltonext < b.totaltonext;
}
bool isvalue(point n)
{
return (n.x >= 1 && n.x <= 5 && n.y >= 1 && n.y <= 6 && !board[n.x][n.y]);
}
1153
#include <iostream>
#include <vector>
#include <memory.h>
#include <algorithm>
using namespace std;
struct point
{
int x;
int y;
int totaltonext;
};
int board[10][10];
int move_x[] = {-1, -1, -2, -2, 1, 1, 2, 2};
int move_y[] = {-2, 2, 1, -1, 2, -2, 1, -1};
bool isfind;
int path[100];
bool dfs(point, int);
bool isvalue(point );
bool cmp(point , point );
int main()
{
int n;
point p;
//freopen("C:\\Users\\Haojian\\Desktop\\test.txt", "r", stdin);
while (cin >> n && n != -1)
{
isfind = false;
memset(board, 0, 10*10*sizeof(int));
p.x = (n - 1) / 8 + 1;
p.y = n - ((p.x-1) * 8);
//p.num = 1;
// path[p.num-1] = n;
path[0] = n;
board[p.x][p.y] = 1;
dfs (p, 1);
}
return 0;
}
bool dfs (point p, int current)
{
point n;
if (current == 64)
{
for (int i = 0; i < 63; i++)
cout << path[i] << " ";
cout << path[63];
cout << endl;
return true;
}
else
{
vector<point> tmp;
for (int i = 0; i < 8; i++)
{
n.x = p.x + move_x[i];
n.y = p.y + move_y[i];
n.totaltonext = 0;
if (isvalue(n))
{
point k;
for (int j = 0; j < 8; j++)
{
k.x = n.x + move_x[j];
k.y = n.y + move_y[j];
if (isvalue(k))
n.totaltonext++;
}
tmp.push_back(n);
}
}
sort(tmp.begin(), tmp.end(), cmp);
for (int i = 0; i < tmp.size(); i++)
{
board[tmp[i].x][tmp[i].y] = 1;
path[current] = (tmp[i].x - 1) * 8 + tmp[i].y;
if (dfs(tmp[i], current+1)) return true;
board[tmp[i].x][tmp[i].y] = 0;
}
}
return false;
}
bool cmp(point a, point b)
{
return a.totaltonext < b.totaltonext;
}
bool isvalue(point n)
{
return (n.x >= 1 && n.x <= 8 && n.y >= 1 && n.y <= 8 && !board[n.x][n.y]);
}
浙公网安备 33010602011771号