POJ 1198/HDU 1401

双向广搜。。。

呃,双向广搜一般都都用了HASH判重,这样可以更快判断两个方向是否重叠了。这道题用了双向的BFS,有效地减少了状态。但代码太长了,不写,贴一个别人的代码。。

  1 #include<iostream>
  2 #include<set>
  3 #include<queue>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 typedef __int64 i64;
  8 
  9 const  i64  one = (i64)1;
 10 const  int  maxn = 1<<17 ;
 11 int dx[4] = { 1 , 0 ,-1 , 0  } ;
 12 int dy[4] = { 0 , 1 , 0 , -1 };
 13 
 14 struct node
 15 {   
 16      i64  bd;
 17      int pos[4];
 18 };
 19 
 20 node st , ed ;
 21 
 22 i64  stq[maxn] ,edq[maxn]  , sz ,ez ;
 23 
 24 set<i64> win ;
 25 set<i64>:: iterator it ;
 26 
 27 bool  IsOut( int cx,int cy)
 28 {     
 29       return cx <0 || cy < 0 || cx >=8 || cy >=8 ;
 30 }
 31 
 32 bool  IsOn( i64 bd ,int cx, int cy)
 33 {     
 34       return  bd & ( one<<(cx * 8 + cy) ) ;
 35 }
 36 
 37 void  clr( i64 &bd ,int i)
 38 {     
 39       if( ! IsOn( bd , i/8 , i%8) ) return ;
 40       bd -= one<<i;
 41 }
 42 
 43 void  put( i64 &bd, int i )
 44 {    
 45       if(IsOn(bd ,i/8 ,i%8) )   return ;
 46       bd += one <<i ;
 47 }
 48 
 49 
 50 bool next(node cur, int i,int j , node &son)
 51 {    
 52      int t , tx , ty , nx , ny , cx , cy ;
 53      i64 bd = cur.bd;
 54      t = cur.pos[i] , tx = t / 8  , ty = t % 8 ;
 55      nx = tx + dx[j] , ny = ty + dy[j] ;
 56      if( IsOut(nx, ny) )  return false;
 57      if( IsOn (bd , nx, ny) )  
 58      {     
 59            cx = 2*nx - tx, cy = 2*ny - ty;
 60            if( IsOut(cx , cy) || IsOn(bd , cx , cy) )  return false;
 61            clr(cur.bd, tx*8 + ty);
 62            put(cur.bd, cx*8 + cy);
 63            cur.pos[i] = cx * 8 + cy;
 64            son = cur;
 65            return  true;
 66      }
 67      clr(cur.bd , tx * 8 + ty);  put(cur.bd , nx * 8 + ny);
 68      cur.pos[i] = nx * 8 + ny ;
 69      son =  cur;
 70      return true;
 71 }
 72 
 73 void  deal(node bgn )
 74 {    
 75       int i , j  , dep =  0  ;
 76       node cur , son , tail;
 77       queue<node> q; 
 78          
 79       tail.bd = -1 ;
 80       win.clear();        win.insert(bgn.bd);
 81       q.push(tail);       q.push(bgn);
 82       while(!q.empty()) 
 83       {      
 84              cur = q.front();  q.pop();
 85              if( cur.bd == -1 )
 86              {      
 87                     if(q.empty()) return ;
 88                     q.push(tail);  cur = q.front() ; q.pop();
 89                     if( ++ dep > 4 )  return ; 
 90              }
 91              for(i = 0 ; i < 4 ;++i)
 92                  for( j = 0 ;j < 4 ;++j )
 93                     if ( next( cur , i , j , son ) ) 
 94                          if( win.find(son.bd) ==win.end() ) 
 95                          {   
 96                              q.push(son);
 97                              win.insert(son.bd);
 98                          }
 99       }
100 }
101 
102 int bbs(i64  x)
103 {    
104     int l , r ,mid;
105     l = 0 , r = ez - 1 ;
106     while(l <= r) 
107     {    
108          mid = ( l + r) / 2 ;
109          if(edq[ mid ] == x)  return mid ;
110          else  if ( x < edq[mid] ) r = mid - 1;
111          else   l = mid + 1;
112     }
113     return -1;
114 }
115 
116 bool can()
117 {    
118      int i , x[4],y[4] ,check ;
119      if(scanf("%d%d%d%d%d%d%d%d",&x[0],&y[0],&x[1],&y[1],&x[2],&y[2],&x[3],&y[3]) == EOF )
120          return false;
121      st.bd = 0 ;
122      for(i = 0 ; i<4 ; ++i)
123      {   
124          -- x[i] , -- y[i] ;
125          put(st.bd , x[i] * 8 + y[i]);
126          st.pos[i] = x[i] * 8 + y[i];
127      }    
128      
129      ed.bd = 0 ;
130      for(i = 0 ; i<4 ; ++i)
131      {    
132          scanf("%d%d",&x[i],&y[i]);
133          -- x[i] , -- y[i];
134          put(ed.bd , x[i] * 8 + y[i]);
135          ed.pos[i] = x[i] * 8 + y[i] ;
136      }
137      
138      sz =  ez = 0 ;
139      
140      deal(st);
141      for(it = win.begin() ; it!=win.end(); it ++ )
142           stq[sz ++ ] = *it;
143           
144      deal(ed);
145      for(it = win.begin() ; it!=win.end(); it++)
146          edq[ez ++ ] =  *it ;
147      
148      sort(edq , edq + ez);
149      
150      check =  0 ;
151      for(i = 0 ; i < sz && !check ; ++i)
152        if( bbs(stq[i]) !=-1 )  
153             check = 1;  
154     
155      if(check)
156            cout<<"YES"<<endl;
157      else 
158            cout<<"NO"<<endl;
159      return true;
160 }
161 
162 int main()
163 {    
164      while(can());
165      return 0;
166 }
View Code
原文地址:https://www.cnblogs.com/jie-dcai/p/3803168.html