HDU_1175_A*
http://acm.split.hdu.edu.cn/showproblem.php?pid=1043
刚开始一脸蒙逼,看了题解之后,参考了A*算法。
参考:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
还用到了变进制Hash全排列来判断结果是否满足条件。
参考:http://www.chinaunix.net/old_jh/23/1283459.html
第一次接触A*,感觉类似BFS,不同的是它可以更快地找到最优解。
最后要注意路径的保存,最终用dfs的printff输出。
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<cstdio> #define MAX 322560 using namespace std; struct Node { int a[9],g,h,num,Hash; friend bool operator<(const Node x,const Node y) { return x.h+x.g>y.h+y.g; } }start; int HASH[9]={1,1,2,6,24,120,720,5040,40320}; int vis[400000],pre[400000],dis[4] = {-3,-1,3,1}; int a[3][3]; int get_Hash(Node x) { int ans = 0; for(int i = 0;i < 9;i++) { int k = 0; for(int j =0;j <i;j++) { if(x.a[j]>x.a[i]) k++; } ans += HASH[i]*k; } return ans; } int get_h(Node x) { //»ñµÃ¹À¼Ûº¯ÊýH int ans=0; for(int i=0;i<9;i++) { if(x.a[i] == 0) continue; ans += abs(i/3-(x.a[i]-1)/3)+abs(i%3-(x.a[i]-1)%3); } return ans; } void printff(int h) { if(pre[h] == -1) return; printff(pre[h]); switch (vis[h]) { case 0: printf("u"); break; case 1: printf("l"); break; case 2: printf("d"); break; case 3: printf("r"); break; } } int main() { char str[50]; while(gets(str)) { memset(vis,-1,sizeof(vis)); memset(pre,-1,sizeof(pre)); int now = 0,num = 0; for(int i = 0;i < 3;i++) { for(int j = 0;j < 3;j++,now++) { if(str[now] >= '0' && str[now] <= '9') { start.a[num++] = str[now]-'0'; } else if(str[now] == 'x') { start.num = num; start.a[num++] = 0; } else j--; } } num = 0; for(int i = 0;i < 9;i++) { for(int j = i+1;j <9;j++) { if(start.a[i] && start.a[j] && start.a[i]>start.a[j]) num++; } } if(num%2) { printf("unsolvable\n"); continue; } start.Hash = get_Hash(start); if(start.Hash == MAX) { printf("\n"); continue; } start.g = 0; start.h = get_h(start); vis[start.Hash] = -2; priority_queue<Node> q; q.push(start); while(!q.empty()) { Node temp = q.top(); int xx = temp.num/3,yy = temp.num%3; q.pop(); for(int i = 0;i < 4;i++) { Node x = temp; x.num += dis[i]; if(yy == 0 && i == 1) continue; if(yy == 2 && i == 3) continue; if(x.num < 0 || x.num > 8) continue; swap(x.a[x.num],x.a[temp.num]); x.Hash = get_Hash(x); if(vis[x.Hash] != -1) continue; x.g++; x.h = get_h(x); q.push(x); pre[x.Hash] = temp.Hash; vis[x.Hash] = i; if(x.Hash == MAX) goto there; } } there: printff(MAX); printf("\n"); } }