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 }