折半搜索就好了。
用个map记忆一下。
记录旗子的位置再排序也能做。
但是考虑到8*8正好能用long long压一下,所以我是状压了棋盘。
注意如果用dfs不要判重,有可能状态一样,但是步数不同。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 typedef unsigned long long ull; 7 const ull u=1ull; 8 9 int ans; 10 ull st,ed; 11 map<ull,int>mp; 12 13 int dfs(ull s,int kd,int r) 14 { 15 if(mp[s]==3-kd)return 1; 16 mp[s]=kd; 17 if(!r)return 0; 18 r--; 19 int ret=0; 20 for(int i=0;i<64;i++) 21 { 22 if(!(s&(u<<i)))continue; 23 ull to=s^(u<<i); 24 if(i%8<7&&(!(s&(u<<i+1)))) 25 ret|=dfs(to|(u<<i+1),kd,r); 26 if(i%8<6&&(s&(u<<i+1))&&(!(s&(u<<i+2)))) 27 ret|=dfs(to|(u<<i+2),kd,r); 28 if(i%8>0&&(!(s&(u<<i-1)))) 29 ret|=dfs(to|(u<<i-1),kd,r); 30 if(i%8>1&&(s&(u<<i-1))&&(!(s&(u<<i-2)))) 31 ret|=dfs(to|(u<<i-2),kd,r); 32 if(i>=8&&(!(s&(u<<i-8)))) 33 ret|=dfs(to|(u<<i-8),kd,r); 34 if(i>=16&&(s&(u<<i-8))&&(!(s&(u<<i-16)))) 35 ret|=dfs(to|(u<<i-16),kd,r); 36 if(i+8<64&&(!(s&(u<<i+8)))) 37 ret|=dfs(to|(u<<i+8),kd,r); 38 if(i+16<64&&(s&(u<<i+8))&&(!(s&(u<<i+16)))) 39 ret|=dfs(to|(u<<i+16),kd,r); 40 } 41 return ret; 42 } 43 44 int main() 45 { 46 int pos[4][2]; 47 while(scanf("%d%d",&pos[0][0],&pos[0][1])!=EOF) 48 { 49 mp.clear(); 50 ans=st=ed=0; 51 for(int i=1;i<4;i++) 52 scanf("%d%d",&pos[i][0],&pos[i][1]); 53 for(int i=0;i<4;i++) 54 for(int j=0;j<2;j++)pos[i][j]--; 55 for(int i=0;i<4;i++) 56 st|=(u<<((pos[i][0]<<3)+pos[i][1])); 57 for(int i=0;i<4;i++) 58 scanf("%d%d",&pos[i][0],&pos[i][1]); 59 for(int i=0;i<4;i++) 60 for(int j=0;j<2;j++)pos[i][j]--; 61 for(int i=0;i<4;i++) 62 ed|=(u<<((pos[i][0]<<3)+pos[i][1])); 63 dfs(st,1,4); 64 ans=dfs(ed,2,4); 65 printf(ans?"YES ":"NO "); 66 } 67 return 0; 68 }