hdu 1043 #八数码#全排列逆序对的哈希+BFS
2012-07-25 12:21
183 查看
之前这题超时的,因为每次都BFS了。
当时实在是蠢了,其实只要以终态为起点一次BFS就记录好所有路径了
当时实在是蠢了,其实只要以终态为起点一次BFS就记录好所有路径了
#include <stdio.h> #include <queue> #include <iostream> #include <string.h> using namespace std; #define N 1000000 struct node { int x,y; char mat[3][3]; }p,pt; char dir ; int nxt ; int move[][2] = {0,1,1,0,0,-1,-1,0}; char mo[5] = "lurd"; int fac[] = {1,1,2,6,24,120,720,5040,40320}; bool inner(int x,int y) { return x >=0 && x < 3 && y >=0 && y < 3; } int get_hash(node p) { int i,j,k,ans = 0,d; char temp[10]; for(i = 0; i < 3; ++i) for(j = 0; j < 3; ++j) { temp[i*3+j] = p.mat[i][j]; d = 0; for(k = 0; k < i * 3 + j; ++k) if(temp[k] > p.mat[i][j]) ++d; ans += fac[i*3+j] * d; } return ans; } void bfs() { for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) p.mat[i][j] = '1' + i * 3 + j; p.mat[2][2] = '0'; p.x = p.y = 2; memset(nxt,-1,sizeof(nxt)); queue<node> que; que.push(p); int hh,h = get_hash(p); nxt[h] = -2; dir[h] = '\n'; while(!que.empty()) { p = que.front(); que.pop(); h = get_hash(p); for(int i = 0; i < 4; ++i) { pt = p; pt.x += move[i][0]; pt.y += move[i][1]; if(inner(pt.x,pt.y)) { swap(pt.mat[p.x][p.y],pt.mat[pt.x][pt.y]); hh = get_hash(pt); if(nxt[hh] == -1) { nxt[hh] = h; dir[hh] = mo[i]; que.push(pt); } } } } } int main() { bfs(); int i,j; while(cin >> p.mat[0][0]) { cin >> p.mat[0][1] >> p.mat[0][2]; for(i = 1; i < 3; ++i) for(j = 0; j < 3; ++j) cin >>p.mat[i][j]; for(i = 0; i < 3; ++i) for(j = 0; j < 3; ++j) if(p.mat[i][j] == 'x') p.mat[i][j] = '0'; int h = get_hash(p); if(nxt[h] == -1) printf("unsolvable\n"); else { for(; nxt[h] != -2; h = nxt[h]) printf("%c",dir[h]); printf("\n"); } } return 0; }
#include<iostream> #include<queue> #include<cstdio> #include<cmath> #include<cstring> using namespace std; char ms[6]="rdul"; int vis[400000],id; int pre[600000]; char path[600000]; int fac[]={1,1,2,6,24,120,720,5040,40320}; struct node { int pos,id; int s[9]; }p,p2; int hash(int *str) { int i,j,cnt,res=0,jac=1; for(i=1;i<9;++i) { cnt=0; for(j=0;j<i;++j) if(str[j]>str[i]) ++cnt; res+=cnt*fac[i]; } return res; } void output(int s) { char str[400000]; int k=0; while(s) { str[k++]=path[s]; s=pre[s]; } for(k--;k>=0;--k) printf("%c",str[k]); printf("\n"); } //int final=hash("123456789");//终态的哈希值为0 int bfs() { queue<node> que; int h; h=hash(p.s); if(!h) { printf("\n"); return 1; } memset(vis,0,sizeof(vis)); p.id=0; que.push(p); vis[h]=1; id=0; while(!que.empty()) { p=que.front(); que.pop(); if(p.pos%3!=2) { p2=p; swap(p2.s[p.pos],p2.s[p.pos+1]); h=hash(p2.s); if(!vis[h]) { vis[h]=1; p2.id=++id; pre[id]=p.id; path[id]=ms[0]; if(!h) { output(id); return 1; } p2.pos=p.pos+1; que.push(p2); } } if(p.pos%3) { p2=p; swap(p2.s[p.pos],p2.s[p.pos-1]); h=hash(p2.s); if(!vis[h]) { vis[h]=1; p2.id=++id; pre[id]=p.id; path[id]=ms[3]; if(!h) { output(id); return 1; } p2.pos=p.pos-1; que.push(p2); } } if(p.pos>2) { p2=p; swap(p2.s[p.pos],p2.s[p.pos-3]); h=hash(p2.s); if(!vis[h]) { vis[h]=1; p2.id=++id; pre[id]=p.id; path[id]=ms[2]; if(!h) { output(id); return 1; } p2.pos=p.pos-3; que.push(p2); } } if(p.pos<6) { p2=p; swap(p2.s[p.pos],p2.s[p.pos+3]); h=hash(p2.s); if(!vis[h]) { vis[h]=1; p2.id=++id; pre[id]=p.id; path[id]=ms[1]; if(!h) { output(id); return 1; } p2.pos=p.pos+3; que.push(p2); } } } return 0; } int main() { int i,j=0; char e[3]; while(scanf("%s",e)==1) { if(e[0]=='x') { p.s[0]=9; p.pos=0; } else p.s[0]=e[0]-'0'; for(i=1;i<9;++i) { scanf("%s",e); if(e[0]=='x') { p.s[i]=9; p.pos=i; } else p.s[i]=e[0]-'0'; } if(!bfs()) printf("unsolvable\n"); } return 0; }
相关文章推荐
- HDU 1043 全排列 康托展开
- [HDU 1394]求全排列逆序数最大值[线段树]
- HDU 1043 八数码问题 A*搜索+康拓展开+逆序对判断+路径输出
- hdu-1394-逆序数
- 2017多校第二场 HDU 6048 Puzzle 逆序数,脑洞题,结论题
- 51Nod 1020 逆序排列
- poj 1077 hdu 1043 Eight 八数码问题 DBFS(双向广度优先搜索)a*算法 康拓展开
- HDU 1027 全排列
- HDU 1043 Eight(经典八数码)(BFS+STL)
- LightOJ 1139 8 puzzle + hdu 1043 Eight A*
- HDU-1394 求逆序对数
- 【归并排序】【逆序数】HDU 5775 Bubble Sort
- 将一个链表按逆序排列
- HDU 1716 排列2 字典序
- 逆序排列
- 2. Add Two Numbers 给定的两个链表是逆序排列的,相加后放在一个新的链表里边
- hdu 1043 Eight(八数码)
- HDU-4661 Message Passing 树形DP,排列组合
- HDU1043 Eight[bfs]
- 八数码[POJ-1077 | HDU-1043] BFS A* IDA* 双广