POJ 1077 八数码问题 练习搜索
来源:互联网 发布:疯狂粤语 粤知一二 编辑:程序博客网 时间:2024/05/16 14:55
简单bfs+康托展开判重,足以过掉。
一会再写 双向 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 dint 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 dint 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;}
0 0
- POJ 1077 八数码问题 练习搜索
- Poj 1077 Eight 八数码问题 (搜索)
- POJ 1077 八数码问题
- POJ 1077 八数码问题
- POJ 1077 Eight(BFS八数码问题)
- POJ 1077 Eight, 八数码问题
- POJ 1077 Eight 八数码问题 BFS
- POJ 1077 Eight 八数码问题 A*
- IDA* 解八数码问题: POJ 1077
- 八数码问题(启发式搜索)
- 【启发式搜索】八数码问题
- A*搜索 - 八数码问题
- Vijos1360[八数码问题] 搜索
- 搜索 ( 八数码问题详解:BFS,A*,IDA* )——Eight ( POJ 1077 )
- poj 1077 八数码
- poj 1077 八数码
- poj 1077 八数码
- POJ 1077 Eight 八数码 A*搜索算法
- 我的android(第五天)
- oracle ORA-01438
- 理解python装饰器
- Construct Binary Tree from Inorder and Postorder Traversal
- 字符串
- POJ 1077 八数码问题 练习搜索
- 有关main的返回值
- ORACLE EXTRACT函数
- 第三周练习题目——二分法1 水的高度
- 算法学习(四)冒泡排序
- MFC不同对话框之间的数据传递
- HDU 1513 Palindrome
- (25)ExtJS之面板Panel
- Android中的HAL相关库搜索机制和原理学习