转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
第一次写双向BFS。
双向BFS即是从起点和终点开始搜,如果出现交点,说明目标点可达。这点要求是八步之内到达,每步有16个状态,16^8的复杂度还是很高的,由于是确定了起点和终点的,十分适合双向BFS,即从起点和终点分别开始搜4步,如果出现交点则说明可达。
HASH的时候采用进制压缩,每个坐标范围为0-7可以用三位二进制表示,总共便是24位二进制表示,其中在HASH的时候注意要把坐标排序。一开始直接用flag[1<<24]结果还是MLE了。后来改成map,不是很习惯。
虽然写成了一个BFS,不过中间部分写得很矬。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define inf 1<<30
#define LL long long
#define maxn 1<<24
using namespace std;
struct Point{
int x,y;
bool check(){
if(x<8&&x>=0&&y<8&&y>=0)
return true;
return false;
}
};
struct Node{
Point pos[4];
int step;
}s,e;
map<int,int>m;
map<int,int>::iterator it;
int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool cmp(Point n1,Point n2){
return n1.x!=n2.x?n1.x<n2.x:n1.y<n2.y;
}
int get_hash(Point *tmp){
int res=0;
sort(tmp,tmp+4,cmp);
for(int i=0;i<4;i++){
res|=(tmp[i].x<<(6*i));
res|=(tmp[i].y<<(6*i+3));
}
return res;
}
bool bfs(int kind,Node u){
Node v;
queue<Node>que;
u.step=0;
if(kind==2){
it=m.find(get_hash(u.pos));
if(it!=m.end())
return true;
}
m[get_hash(u.pos)]=kind;
que.push(u);
while(!que.empty()){
u=que.front();
que.pop();
if(u.step>=4)
continue;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
v=u;v.step++;
v.pos[j].x+=way[i][0];
v.pos[j].y+=way[i][1];
int k;
if(!v.pos[j].check())
continue;
for(k=0;k<4;k++)
if(k!=j&&v.pos[k].x==v.pos[j].x&&v.pos[k].y==v.pos[j].y)
break;
if(k==4){
int HASH=get_hash(v.pos);
it=m.find(HASH);
if(kind==1){
if(it==m.end()){
m[HASH]=1;
que.push(v);
}
}
else{
if(it==m.end()){
m[HASH]=2;
que.push(v);
}
else if((*it).second==1)
return true;
}
}
else{
v.pos[j].x+=way[i][0];
v.pos[j].y+=way[i][1];
if(!v.pos[j].check())
continue;
for(k=0;k<4;k++)
if(k!=j&&v.pos[k].x==v.pos[j].x&&v.pos[k].y==v.pos[j].y)
break;
if(k==4){
int HASH=get_hash(v.pos);
it=m.find(HASH);
if(kind==1){
if(it==m.end()){
m[HASH]=1;
que.push(v);
}
}
else{
if(it==m.end()){
m[HASH]=2;
que.push(v);
}
else if((*it).second==1)
return true;
}
}
}
}
}
}
return false;
}
int main(){
while(scanf("%d%d",&s.pos[0].x,&s.pos[0].y)!=EOF){
m.clear();
for(int i=1;i<4;i++)
scanf("%d%d",&s.pos[i].x,&s.pos[i].y);
for(int i=0;i<4;i++)
scanf("%d%d",&e.pos[i].x,&e.pos[i].y);
for(int i=0;i<4;i++){
s.pos[i].x--;s.pos[i].y--;
e.pos[i].x--;e.pos[i].y--;
}
bfs(1,s);
printf("%s\n",bfs(2,e)?"YES":"NO");
}
return 0;
}
/*
2 1 8 8 7 8 1 1
1 5 8 7 7 7 2 4
6 5 5 7 5 1 7 1
7 7 6 5 5 7 6 3
4 6 5 6 5 5 5 2
2 2 7 6 5 3 5 2
4 4 5 5 3 4 7 2
2 7 7 2 6 5 4 8
4 2 3 4 5 5 6 6
2 7 4 4 3 5 4 5
3 3 5 3 6 2 6 6
6 3 8 3 6 6 6 8
3 2 5 3 6 2 6 6
6 3 8 3 6 6 6 8
3 4 4 5 5 5 7 5
3 3 4 3 5 3 6 3
*/