每一步有4*4=16个决策,单向搜索的话有16^8种状态,双向搜索只有32^4种状态,缩小了解空间。
双向搜索用来解决起点和终点确定的搜索问题。方法就是从起点和终点轮流走,分别有各自的队列和标记数组。起点每到一个新的状态,就到终点的标记数组中查询,判断是否有交点。终点也是做一样的操作。
注意:Hash时如果像我一样8进制压缩,每个数必须是0~7的,也就是输入的坐标要减1
代码:
#include <iostream>
#include <cstdio>
#define LL long long
#include <cstring>
using namespace std;
#include <map>
#include <queue>
#include <algorithm>
struct node{
int x,y;
};
node a[4];
node b[4];
bool visa[10][10];
bool visb[10][10];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool cmp(node a,node b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
LL Hash(node c[]){
LL res=0;
for(int i=0;i<4;i++){
res=res*8+c[i].x;
res=res*8+c[i].y;
}
return res;
}
void aHash(LL n,node a[]){
for(int i=3;i>=0;i--){
a[i].y=n%8;
n/=8;
a[i].x=n%8;
n/=8;
}
}
bool valid(int x,int y){
if(x>=0&&x<8&&y>=0&&y<8) return 1;
return 0;
}
bool bfs(){
sort(a,a+4,cmp);
sort(b,b+4,cmp);
queue<LL> Qa;
queue<LL> Qb;
map<LL,int> at;
map<LL,int> bt;
LL cur1=Hash(a);
Qa.push(cur1);
at[cur1]=0;
LL cur2=Hash(b);
if(cur1==cur2) return 1;
Qb.push(cur2);
bt[cur2]=0;
while(!Qa.empty()||!Qb.empty()){
if(!Qa.empty()){
LL cur=Qa.front(); Qa.pop();
if(at[cur]<4){
memset(visa,0,sizeof(visa));
node k[4];
node og[4];
aHash(cur,og);
for(int i=0;i<4;i++){
visa[og[i].x][og[i].y]=1;
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
for(int l=0;l<4;l++) k[l]=og[l];
int tx=k[i].x+dir[j][0];
int ty=k[i].y+dir[j][1];
if(!valid(tx,ty)) continue;
if(visa[tx][ty]){
tx+=dir[j][0];
ty+=dir[j][1];
if(!valid(tx,ty)||visa[tx][ty]) continue;
}
k[i].x=tx; k[i].y=ty;
sort(k,k+4,cmp);
LL nt=Hash(k);
if(at.count(nt)==0){
if(bt.count(nt)>0) return 1;
at[nt]=at[cur]+1;
Qa.push(nt);
}
}
}
}
}
if(!Qb.empty()){
LL cur=Qb.front(); Qb.pop();
if(bt[cur]<4){
memset(visb,0,sizeof(visb));
node k[4];
node og[4];
aHash(cur,og);
for(int i=0;i<4;i++){
visb[og[i].x][og[i].y]=1;
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
for(int l=0;l<4;l++) k[l]=og[l];
int tx=k[i].x+dir[j][0];
int ty=k[i].y+dir[j][1];
if(!valid(tx,ty)) continue;
if(visb[tx][ty]){
tx+=dir[j][0];
ty+=dir[j][1];
if(!valid(tx,ty)||visb[tx][ty]) continue;
}
k[i].x=tx; k[i].y=ty;
sort(k,k+4,cmp);
LL nt=Hash(k);
if(bt.count(nt)==0){
if(at.count(nt)>0) return 1;
bt[nt]=bt[cur]+1;
Qb.push(nt);
}
}
}
}
}
}
return 0;
}
int main(){
while(~scanf("%d%d",&a[0].x,&a[0].y)){
a[0].x--; a[0].y--;
for(int i=1;i<4;i++){
int x,y;
scanf("%d%d",&x,&y);
x--; y--;
a[i].x=x; a[i].y=y;
}
for(int i=0;i<4;i++){
int x,y;
scanf("%d%d",&x,&y);
x--; y--;
b[i].x=x; b[i].y=y;
}
if(bfs()) printf("YES\n");
else printf("NO\n");
}
return 0;
}