HDU - 1043 - Eight(經典八數碼&&各種搜尋) (未完)
阿新 • • 發佈:2018-11-14
單向BFS
#include <bits/stdc++.h> using namespace std; typedef pair<int,char> pic; struct Node { int s[9];//當前排列 int ri,ci;//x的位置 int status;//狀態的康拓對映 int cnt;//移動步數 Node() { memset(s,0,sizeof(s)); ri=ci=0; status=-1; cnt=0; } }; const int dir[4][2]= {-1,0,1,0,0,-1,0,1};// char in[20]; Node st,ed; queue<Node> Q; int fac[9]; bool vis[(int)4e5+10]; map<int,pair<int,int> >pre;//記錄路徑 bool InMap(int ri,int ci) { return ri>=0&&ri<3&&ci>=0&&ci<3; } int Cantor(int s[])//康拓展開求排列序號 { int ret=0; for(int i=0; i<9; i++) { int cnt=0; for(int j=i+1; j<9; j++) { if(s[j]<s[i])cnt++; } ret+=cnt*fac[8-i]; } return ret; } int BFS(const Node& st,int edval) { memset(vis,false,sizeof(vis)); while(!Q.empty())Q.pop(); pre.clear(); Q.push(st); vis[st.status]=true; pre[st.status]=make_pair(-1,-1); while(!Q.empty()) { Node u=Q.front(); Q.pop(); if(u.status==edval)return u.cnt; for(int di=0; di<4; di++) { Node v=u; v.ri=u.ri+dir[di][0]; v.ci=u.ci+dir[di][1]; if(!InMap(v.ri,v.ci))continue; int upos=3*u.ri+u.ci; int vpos=3*v.ri+v.ci; swap(v.s[upos],v.s[vpos]); v.status=Cantor(v.s); if(vis[v.status])continue; vis[v.status]=true; v.cnt=u.cnt+1; Q.push(v); pre[v.status]=make_pair(u.status,di); if(v.status==edval)return v.cnt; } } return -1; } int main() { fac[0]=1; for(int i=1; i<9; i++)fac[i]=i*fac[i-1]; ed.ri=ed.ci=2; for(int i=0; i<9; i++) { ed.s[i]=i+1; } ed.status=Cantor(ed.s); while(cin>>in[0]) { for(int i=1; i<9; i++)cin>>in[i]; for(int ri=0; ri<9; ri++) { if('x'==in[ri]) { st.s[ri]=9; st.ri=ri/3; st.ci=ri%3; } else st.s[ri]=in[ri]-'0'; } st.status=Cantor(st.s); st.cnt=0; int flag=BFS(st,ed.status); if(-1==flag)puts("unsolvable"); else { char ans[1000]; char ch[5]="udlr";//與dir方向對應 int k=ed.status; ans[flag]=0; while(k!=st.status) { flag--; ans[flag]=ch[pre[k].second]; k=pre[k].first; } puts(ans); } } return 0; }
雙向BFS
http://www.cnblogs.com/bofengyu/p/4825529.html
#include <bits/stdc++.h> using namespace std; const int maxn = 362885; //狀態數9! int dir[4] = {-3,3,-1,1}; //某個方向移動對應一維的位置變化 char opf[4] = {'u','d','l','r'};//正向bfs對應的 char opr[4] = {'d','u','r','l'}; int fac[9] = {1,1,2,6,24,120,720,5040,40320};//康拓展開 bool visf[maxn];//標記正向狀態是否訪問 bool visr[maxn]; string targs = "123456789";//目標狀態 struct Node { string s; int xloca; } node; struct Node2 { int idf,idr;//正向前驅和後驅 char cf,cr;//對應的操作 } op[maxn]; int cantor(string s)//求排列對應的康拓展開 { int num = 0; for(int i = 0; i < 9; i++) { int t = 0; for(int j = i + 1; j < 9; j++) { if(s[j] < s[i]) t++; } num += fac[8-i] * t; } return num; } void print(int i)//遞迴輸出 { if(op[i].idf == -1) return; print(op[i].idf); cout<<op[i].cf; } void DoubleBFS() { queue<Node> qf,qr; Node t1,t2; int hash1,hash2,xloca; t1 = node; //初始狀態 t2.s = targs;//目標狀態. t2.xloca = 8;//目標狀態x位置 hash1 = cantor(t1.s); visf[hash1] = true; op[hash1].idf = -1; qf.push(t1); hash1 = cantor(t2.s); visr[hash1] = true; op[hash1].idr = -1; qr.push(t2); while(!qf.empty()&&!qr.empty()) { //正向bfs t1 = qf.front(); qf.pop(); hash1 = cantor(t1.s); if(visr[hash1]) { print(hash1); hash2 = hash1; while(op[hash2].idr != -1) { cout<<op[hash2].cr; hash2 = op[hash2].idr; } cout<<endl; return ; } for(int i = 0; i < 4; i++) { if(i == 0 && t1.xloca < 3) continue; if(i == 1 && t1.xloca > 5) continue; if(i == 2 && t1.xloca%3 == 0) continue; if(i == 3 && t1.xloca%3 == 2) continue; xloca = t1.xloca + dir[i]; t2 = t1; swap(t2.s[t1.xloca],t2.s[xloca]); hash2 = cantor(t2.s); if(!visf[hash2]) { visf[hash2] = true; t2.xloca = xloca; op[hash2].idf = hash1; op[hash2].cf = opf[i]; qf.push(t2); } } //反向bfs t1 = qr.front(); qr.pop(); hash1 = cantor(t1.s); if(visf[hash1]) { print(hash1); hash2 = hash1; while(op[hash2].idr != -1) { cout<<op[hash2].cr; hash2 = op[hash2].idr; } cout<<endl; return; } for(int i = 0; i < 4; i++) { if(i == 0 && t1.xloca < 3) continue; if(i == 1 && t1.xloca > 5) continue; if(i == 2 && t1.xloca%3 == 0) continue; if(i == 3 && t1.xloca%3 == 2) continue; xloca = t1.xloca + dir[i]; t2 = t1; swap(t2.s[t1.xloca],t2.s[xloca]); hash2 = cantor(t2.s); if(!visr[hash2]) { visr[hash2] = true; t2.xloca = xloca; op[hash2].idr = hash1; op[hash2].cr = opr[i]; qr.push(t2); } } } } int main() { string str; int len; int ivsNum;//逆序數 while(getline(cin,str)) { memset(visf,0,sizeof visf); memset(visr,0,sizeof visr); len = str.size(); node.s = ""; int k = 0; for(int i = 0; i < len; i++) { if(str[i]!=' ') { if(str[i] == 'x') { node.s = node.s + '9'; node.xloca = k; } else { node.s = node.s + str[i]; } k++; } } //cout<<node.s<<endl; ivsNum = 0; for(int i = 0; i < 9; i++) { if(node.s[i] == '9') continue; for(int j =0; j < i; j++) { if(node.s[j] == '9') continue; if(node.s[j] > node.s[i]) ivsNum ++; } } if(ivsNum & 1) cout<<"unsolvable"<<endl; else DoubleBFS(); } return 0; }
逆向BFS+離線打表//不完備
#include <bits/stdc++.h> using namespace std; const int N = 512345; char ss[10]; struct node { char str[10]; vector<int> res; int index,num; }; vector<int> res[N]; bool vis[N]; int fac[] = {1,1,2,6,24,120,720,5040,40320}; int over; int ans[N]; int contor(char ss[]) { int t,sum; int s[10]; for(int i = 0; i < 9; i++) { if(ss[i]=='x') s[i] = 0; else s[i]=ss[i]-'0'; } sum = 0; for(int i = 0; i < 9;i++) { t = 0; for(int j = i + 1; j < 9; j++) { if(s[j] < s[i]) t++; } sum += t *fac[9-i-1]; } return sum+1; } void bfs() { char c; queue<node> q; over = contor(ss); node g,h; for(int i = 0; i < 8;i++) { g.str[i] = i + 1 + '0'; } g.str[8] = 'x'; g.str[9] = '\0'; g.res.clear();g.index = 8;g.num = 0; int t = contor(g.str); vis[t] = true; q.push(g); while(!q.empty()) { g = q.front(); q.pop(); int t = contor(g.str); res[t] = g.res; g.num ++; h = g; if((h.index+1)%3 != 0) { swap(h.str[h.index],h.str[h.index+1]); h.index ++; h.res.push_back(4); int t = contor(h.str); if(!vis[t]) { vis[t] = true; q.push(h); } } h = g; if(h.index%3 != 0) { swap(h.str[h.index],h.str[h.index-1]); h.index--; h.res.push_back(3); int t= contor(h.str); if(!vis[t]) { vis[t] = true; q.push(h); } } h = g; if(h.index < 6) { swap(h.str[h.index],h.str[h.index+3]); h.index += 3; h.res.push_back(2); int t = contor(h.str); if(!vis[t]) { vis[t] = 1; q.push(h); } } if(h.index > 2) { swap(h.str[h.index],h.str[h.index-3]); h.index -= 3; h.res.push_back(1); int t = contor(h.str); if(!vis[t]) { vis[t] = 1; q.push(h); } } } } int main() { int k,t,x,y,z; for(int i = 0; i < N; i++) res[i].clear(); bfs(); while(scanf("%s",ss)!=EOF) { memset(vis,false,sizeof vis); for(int i = 1; i < 9; i++) scanf("%s",ss+i); //cout<<ss<<endl; t = contor(ss); // for(int i = 1; i<= 46234;i++ ) // cout<<res[i].size()<<endl; if(res[t].size()!=0 || t == 46234) { for(int i = res[t].size() - 1; i >= 0; i--) { if(res[t][i] == 1) cout<<"d"; else if(res[t][i] == 2) cout<<"u"; else if(res[t][i] == 3) cout<<"r"; else if(res[t][i] == 4) cout<<"l"; } } else cout<<"unsolvable"; cout<<endl; } }