hdu1401 Solitaire【双广】
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 8 const int dx[4]={-1,0,1,0}; 9 const int dy[4]={0,-1,0,1}; 10 11 struct node 12 { 13 int x[4],y[4]; 14 }sn,en,tmp; 15 queue<node> Q[2]; 16 set<int> S[2]; 17 bool flag; 18 19 int ok(node &cur,int k,int d) 20 { 21 if( cur.x[k]<1 || cur.x[k]>8 || cur.y[k]<1 || cur.y[k]>8 ) return 0; 22 bool flag=false; 23 for(int i=0;i<4;i++) 24 if( i!=k && cur.x[k]==cur.x[i] && cur.y[k]==cur.y[i] ){flag=true;break;} 25 if( !flag ) return 1; 26 int nx=cur.x[k]+dx[d],ny=cur.y[k]+dy[d]; 27 if( nx<1 || nx>8 || ny<1 || ny>8 ) return 0; 28 for(int i=0;i<4;i++) 29 if( nx==cur.x[i] && ny==cur.y[i] ) return 0; 30 return 2; 31 } 32 33 bool cmp(int a,int b) 34 { 35 if( tmp.x[a]!=tmp.x[b] ) return tmp.x[a]<tmp.x[b]; 36 else return tmp.y[a]<tmp.y[b]; 37 } 38 39 int hash(node &cur) 40 { 41 int id[4]={0,1,2,3},code=0; 42 43 tmp=cur; 44 sort(id,id+4,cmp); 45 for(int i=0;i<4;i++) code=code*8+cur.x[id[i]]-1; 46 for(int i=0;i<4;i++) code=code*8+cur.y[id[i]]-1; 47 return code; 48 } 49 50 void bfs(int d) 51 { 52 int size=Q[d].size(); 53 while( size-- ) 54 { 55 node cur=Q[d].front(); 56 57 Q[d].pop(); 58 for(int i=0;i<4;i++) 59 for(int j=0;j<4;j++) 60 { 61 node next=cur; 62 int sel,code; 63 64 next.x[i]+=dx[j]; 65 next.y[i]+=dy[j]; 66 sel=ok(next,i,j); 67 if( !sel ) continue; 68 else if( 2==sel ) next.x[i]+=dx[j],next.y[i]+=dy[j]; 69 code=hash(next); 70 if( S[d].find(code)!=S[d].end() ) continue; 71 if( S[d^1].find(code)!=S[d^1].end() ) {flag=true;return;} 72 S[d].insert(code); 73 Q[d].push(next); 74 } 75 } 76 } 77 78 bool dbfs(void) 79 { 80 int code1,code2,cnt=0; 81 82 flag=false; 83 S[0].clear(); 84 S[1].clear(); 85 while( !Q[0].empty() ) Q[0].pop(); 86 while( !Q[1].empty() ) Q[1].pop(); 87 code1=hash(sn); 88 code2=hash(en); 89 if( code1==code2 ) return true; 90 S[0].insert(code1); 91 Q[0].push(sn); 92 S[1].insert(code2); 93 Q[1].push(en); 94 while( ++cnt<=8 ) 95 { 96 if( Q[0].size()<Q[1].size() ) bfs(0); 97 else bfs(1); 98 if( flag ) return flag; 99 } 100 return false; 101 } 102 103 int main() 104 { 105 while( true ) 106 { 107 for(int i=0;i<4;i++) if( scanf("%d%d",&sn.x[i],&sn.y[i])==EOF ) return 0; 108 for(int i=0;i<4;i++) scanf("%d%d",&en.x[i],&en.y[i]); 109 puts(dbfs()?"YES":"NO"); 110 } 111 } 112 /* 113 第一道双广 114 普通bfs的最坏复杂度是C(64,4)=635376 115 由于每一个当前状态可以拓展出16个新状态,从起点和终点出发,每边最多拓展4层 116 那么双广的最坏复杂度2*16^4=2*17=131072 117 */