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 */

 

posted @ 2012-11-24 17:39  kiwi_bird  阅读(305)  评论(0编辑  收藏  举报