POJ 1077 八数码问题 练习搜索
2014-03-12 22:29
323 查看
简单bfs+康托展开判重,足以过掉。
一会再写 双向 bfs 还有 A* 和 IDA *
A*
一会再写 双向 bfs 还有 A* 和 IDA *
#include <stdio.h> #include <iostream> #include <queue> #include <algorithm> #include <map> #include <vector> #include <cmath> #include <string.h> #include <stdlib.h> #include <time.h> #include <fstream> #include <stack> using namespace std; #define READ freopen("acm.in","r",stdin) #define ll long long #define PII pair<int,int> #define PDI pair<double,int> #define PDD pair<double,double> #define MII map<int,int>::iterator #define fst first #define sec second #define MS(x,d) memset(x,d,sizeof(x)) #define INF 0x3f3f3f3f #define ALL(x) x.begin(),x.end() #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define MAX 500000 #define ROOT 0,n-1,1 #define PB push_back #define FOR(a,b,c) for(int a=b;a<c;a++) #define MOD 706679 #define keyTree (ch[ ch[root][1] ][0]) int init; // r l u d int dir[4][2]={0,1,0,-1,-1,0,1,0}; int fac[100]; struct P { int s; int d; }; int used[500000]; P pre[500000]; int cantor(int a) { int num[20]; int res=0; int used[20]; MS(used,0); for(int i=9;i>=1;i--) { int cnt=0; int t=a%10;a/=10; used[t]=1; for(int j=0;j<t;j++) if(!used[j]) cnt++; res+=cnt*fac[i-1]; } return res; } int end; int compose(int t[]) { int res=0; for(int i=0;i<9;i++) { res=res*10+t[i]; } return res; } bool bfs() { MS(used,0); queue<int> q; q.push(init); used[cantor(init)]=1; while(!q.empty()) { int s=q.front(); q.pop(); if(s==end) return true; int tmp=s; int state[15]; for(int i=8;i>=0;i--) { state[i]=tmp%10; tmp/=10; } int x,y; for(int i=0;i<9;i++) if(state[i]==0) { x=i/3; y=i%3; } for(int i=0;i<4;i++) { int tx=x+dir[i][0]; int ty=y+dir[i][1]; int ts[15]; for(int j=0;j<9;j++) ts[j]=state[j]; if(tx>=0&&tx<3&&ty>=0&&ty<3) { swap(ts[x*3+y],ts[tx*3+ty]); int curs=compose(ts); int hash=cantor(curs); if(!used[hash]) { q.push(curs); used[hash]=1; pre[hash]=(P){s,i}; } } } } return false; } int main() { READ; fac[0]=1; for(int i=1;i<=10;i++) fac[i]=fac[i-1]*i; for(int i=1;i<9;i++) end=end*10+i; end*=10; char t[3]; while(scanf("%s",t)!=EOF) { if(t[0]!='x') init=t[0]-'0'; for(int i=0;i<8;i++) { scanf("%s",t); if(t[0]!='x') init=init*10+t[0]-'0'; else init=init*10; } if(bfs()) { stack<int> S; for(int s=end;s!=init;s=pre[cantor(s)].s) S.push(pre[cantor(s)].d); while(!S.empty()) { int d=S.top();S.pop(); switch(d) { case 0: cout<<'r'; break; case 1: cout<<'l'; break; case 2: cout<<'u'; break; case 3: cout<<'d'; break; } } cout<<endl; } else { puts("unsolvable"); } } return 0; }
A*
#include <stdio.h> #include <iostream> #include <queue> #include <algorithm> #include <map> #include <vector> #include <cmath> #include <string.h> #include <stdlib.h> #include <time.h> #include <fstream> #include <stack> using namespace std; #define READ freopen("acm.in","r",stdin) #define ll long long #define PII pair<int,int> #define PDI pair<double,int> #define PDD pair<double,double> #define MII map<int,int>::iterator #define fst first #define sec second #define MS(x,d) memset(x,d,sizeof(x)) #define INF 0x3f3f3f3f #define ALL(x) x.begin(),x.end() #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define MAX 500000 #define ROOT 0,n-1,1 #define PB push_back #define FOR(a,b,c) for(int a=b;a<c;a++) #define MOD 706679 #define keyTree (ch[ ch[root][1] ][0]) int init; // r l u d int dir[4][2]={0,1,0,-1,-1,0,1,0}; int fac[100]; struct P { int s; int d; }; struct node { int s; int G; int H; bool operator < (const node &o) const { return (G+H)>(o.G+o.H); } }; int used[500000]; P pre[500000]; int cantor(int a) { int num[20]; int res=0; int used[20]; MS(used,0); for(int i=9;i>=1;i--) { int cnt=0; int t=a%10;a/=10; used[t]=1; for(int j=0;j<t;j++) if(!used[j]) cnt++; res+=cnt*fac[i-1]; } return res; } int rev(int a) { int res=0; int used[20]; for(int i=0;i<9;i++) { int t=a%10;a/=10; used[t]=1; for(int i=0;i<t;i++) if(used[i]) res++; } return res; } int end; int compose(int t[]) { int res=0; for(int i=0;i<9;i++) { res=res*10+t[i]; } return res; } bool bfs() { fill(used,used+500000,INF); //queue<int> q; priority_queue<node> q; q.push((node){init,0,0}); used[cantor(init)]=0; while(!q.empty()) { node tn=q.top(); int pahash=cantor(tn.s); int s=tn.s; q.pop(); if(s==end) return true; int tmp=s; int state[15]; for(int i=8;i>=0;i--) { state[i]=tmp%10; tmp/=10; } int x,y; for(int i=0;i<9;i++) if(state[i]==0) { x=i/3; y=i%3; } for(int i=0;i<4;i++) { int tx=x+dir[i][0]; int ty=y+dir[i][1]; int ts[15]; for(int j=0;j<9;j++) ts[j]=state[j]; if(tx>=0&&tx<3&&ty>=0&&ty<3) { swap(ts[x*3+y],ts[tx*3+ty]); int curs=compose(ts); int hash=cantor(curs); if(used[hash]>used[pahash]+1) { q.push((node){curs,used[pahash]+1,rev(curs)}); used[hash]=used[pahash]+1; pre[hash]=(P){s,i}; } } } } return false; } int main() { READ; fac[0]=1; for(int i=1;i<=10;i++) fac[i]=fac[i-1]*i; for(int i=1;i<9;i++) end=end*10+i; end*=10; char t[3]; while(scanf("%s",t)!=EOF) { if(t[0]!='x') init=t[0]-'0'; for(int i=0;i<8;i++) { scanf("%s",t); if(t[0]!='x') init=init*10+t[0]-'0'; else init=init*10; } if(bfs()) { stack<int> S; for(int s=end;s!=init;s=pre[cantor(s)].s) S.push(pre[cantor(s)].d); while(!S.empty()) { int d=S.top();S.pop(); switch(d) { case 0: cout<<'r'; break; case 1: cout<<'l'; break; case 2: cout<<'u'; break; case 3: cout<<'d'; break; } } cout<<endl; } else { puts("unsolvable"); } } return 0; }
相关文章推荐
- 搜索 ( 八数码问题详解:BFS,A*,IDA* )——Eight ( POJ 1077 )
- Poj 1077 Eight 八数码问题 (搜索)
- 双向BFS解八数码问题: POJ 1077
- poj 1077--Eight(八数码问题,BFS,A*,全排列的哈希)
- HDU 1043 Eight(经典八数码问题)对比POJ 1077
- POJ 1077 Eight && HDU 1043 Eight 八数码问题(A*算法)
- poj1321--棋盘问题(搜索练习2,变形的八皇后问题)
- hdu 1034 & poj 1077 Eight 传说中的八数码问题。真是一道神题,A*算法+康托展开
- POJ1077、HDU1043 Eight 八数码问题:双向BFS、A*
- poj 1077 bfs+康托展开(8数码问题)
- Poj 1077 eight(BFS+全序列Hash解八数码问题)
- 八数码问题 poj 1077 康拓展开
- POJ 1077 Eight 八数码问题 BFS
- POJ1077(经典的八数码问题)
- POJ 1321 棋盘问题(DFS板子题,简单搜索练习)
- POJ 1077 Eight(bfs八数码问题)
- POJ 1077 Eight【八数码问题】
- Poj 1077 eight(BFS+全序列Hash解八数码问题)
- 【hdu1043 && poj 1077】八数码问题
- POJ 1077 八数码问题