/*
马周游,深度为29的深搜
直接进行深搜的话半天都出不了结果,需要对可到达的所有点进行优先级排序
排序标准是这个点的可到达数,可到达数越少的点要优先到达
*/
/*
Run Time: 0secs
Run Memory: 312KB
*/
#include <iostream>
#include <algorithm> //sort等
#include <memory.h> //memset初始化
#include <vector>
using namespace std;
int N; //表示起点 1-30
int X[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int Y[] = {1, 2, 2, 1, -1, -2, -2, -1};
int walked[31];
int result[31];
typedef struct Point{
int x,y,num;
Point(int xx, int yy, int numnum){
x = xx;
y = yy;
num = numnum;
}
};
int cmp(Point a, Point b){
return a.num < b.num;
}
//编号从1开始,二维数组从0开始
inline void oneToTwo(const int& n, int& x, int& y){
x = (n-1) / 6;
y = (n-1) % 6;
}
inline void twoToOne(const int& x, const int& y, int& n){
n = (x * 6) + y + 1;
}
//计算某个点可达下一步的数量
inline int computeNum(const int& x, const int& y){
int result = 0;
for(int i=0; i<8; i++){
int newX = x + X[i];
int newY = y + Y[i];
if(newX>=0 && newY>=0 && newX<=4 && newY <=5){
int num;
twoToOne(newX, newY, num);
if(walked[num] == 0)
result++;
}
}
return result;
}
inline bool walk(int start, int count){
result[count] = start;
int x, y;
oneToTwo(start, x, y);
if(count >= 29)
return true;
//整理可以到达的下一步
vector<Point> roads;
for(int i=0; i<8; i++){
int newX = x + X[i];
int newY = y + Y[i];
if(newX>=0 && newY>=0 && newX<=4 && newY <=5){
int num;
twoToOne(newX, newY, num);
if(walked[num] == 0){
Point buf(newX, newY, computeNum(newX, newY));
roads.push_back(buf);
}
}
}
sort(roads.begin(), roads.end(), cmp);
//按照下一步的可扩展数由小到大去试
for(int i=0; i<roads.size(); i++){
int num;
twoToOne(roads[i].x, roads[i].y, num);
walked[num] = 1;
if(walk(num, count+1))
return true;
walked[num] = 0;
}
return false;
}
int main()
{
while (cin>>N && N!=-1){
memset(walked, 0, sizeof(int)*31);
memset(result, 0, sizeof(int)*31);
walked[N] = 1;
walk(N, 0);
cout << result[0];
for(int i=1; i<30; i++)
cout << " " << result[i];
cout << endl;
}
return 0;
}
Sicily 1152 简单的马周游问题[Speical judge]
最新推荐文章于 2016-04-25 14:08:44 发布