hdu1401 Solitaire【双广】
2012-11-24 17:39
363 查看
#include<cstdio> #include<cstring> #include<set> #include<queue> #include<algorithm> using namespace std; const int dx[4]={-1,0,1,0}; const int dy[4]={0,-1,0,1}; struct node { int x[4],y[4]; }sn,en,tmp; queue<node> Q[2]; set<int> S[2]; bool flag; int ok(node &cur,int k,int d) { if( cur.x[k]<1 || cur.x[k]>8 || cur.y[k]<1 || cur.y[k]>8 ) return 0; bool flag=false; for(int i=0;i<4;i++) if( i!=k && cur.x[k]==cur.x[i] && cur.y[k]==cur.y[i] ){flag=true;break;} if( !flag ) return 1; int nx=cur.x[k]+dx[d],ny=cur.y[k]+dy[d]; if( nx<1 || nx>8 || ny<1 || ny>8 ) return 0; for(int i=0;i<4;i++) if( nx==cur.x[i] && ny==cur.y[i] ) return 0; return 2; } bool cmp(int a,int b) { if( tmp.x[a]!=tmp.x[b] ) return tmp.x[a]<tmp.x[b]; else return tmp.y[a]<tmp.y[b]; } int hash(node &cur) { int id[4]={0,1,2,3},code=0; tmp=cur; sort(id,id+4,cmp); for(int i=0;i<4;i++) code=code*8+cur.x[id[i]]-1; for(int i=0;i<4;i++) code=code*8+cur.y[id[i]]-1; return code; } void bfs(int d) { int size=Q[d].size(); while( size-- ) { node cur=Q[d].front(); Q[d].pop(); for(int i=0;i<4;i++) for(int j=0;j<4;j++) { node next=cur; int sel,code; next.x[i]+=dx[j]; next.y[i]+=dy[j]; sel=ok(next,i,j); if( !sel ) continue; else if( 2==sel ) next.x[i]+=dx[j],next.y[i]+=dy[j]; code=hash(next); if( S[d].find(code)!=S[d].end() ) continue; if( S[d^1].find(code)!=S[d^1].end() ) {flag=true;return;} S[d].insert(code); Q[d].push(next); } } } bool dbfs(void) { int code1,code2,cnt=0; flag=false; S[0].clear(); S[1].clear(); while( !Q[0].empty() ) Q[0].pop(); while( !Q[1].empty() ) Q[1].pop(); code1=hash(sn); code2=hash(en); if( code1==code2 ) return true; S[0].insert(code1); Q[0].push(sn); S[1].insert(code2); Q[1].push(en); while( ++cnt<=8 ) { if( Q[0].size()<Q[1].size() ) bfs(0); else bfs(1); if( flag ) return flag; } return false; } int main() { while( true ) { for(int i=0;i<4;i++) if( scanf("%d%d",&sn.x[i],&sn.y[i])==EOF ) return 0; for(int i=0;i<4;i++) scanf("%d%d",&en.x[i],&en.y[i]); puts(dbfs()?"YES":"NO"); } } /* 第一道双广 普通bfs的最坏复杂度是C(64,4)=635376 由于每一个当前状态可以拓展出16个新状态,从起点和终点出发,每边最多拓展4层 那么双广的最坏复杂度2*16^4=2*17=131072 */
相关文章推荐
- HDU1401 Solitaire 双向搜索
- hdu1401 Solitaire (双向bfs)
- HDU1401 - Solitaire - 双向bfs+哈希状态压缩
- HDU1401-Solitaire
- HDU1401:Solitaire(BFS)
- hdu1401 Solitaire ----双向BFS
- Hdu1401-Solitaire(双向bfs)
- Hdu1401 Solitaire
- UVa 10651 Pebble Solitaire (DFS)
- cf-208B - Solitaire-记录状态DFS
- POJ 1198 Solitaire (双向广搜)
- UVA 10651 Pebble Solitaire(记忆化)
- uva 10651 Pebble Solitaire
- CF 208B Solitaire (记忆化搜索)
- hdu 1401 Solitaire (双向广搜)
- ZOJ 1505 Solitaire(双向广搜)
- hdu1401(双广搜)
- Pebble Solitaire - UVa 10651 状压dp+记忆化搜素
- UVa 10651 - Pebble Solitaire
- HDOJ 题目1401 Solitaire(双向BFS)