Sicily 1152 简单的马周游问题[Speical judge]
来源:互联网 发布:婚庆视频制作软件 编辑:程序博客网 时间:2024/06/07 01:59
/*马周游,深度为29的深搜直接进行深搜的话半天都出不了结果,需要对可到达的所有点进行优先级排序排序标准是这个点的可到达数,可到达数越少的点要优先到达 *//*Run Time: 0secsRun 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;}