每一步有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; }