HDU 1401 Solitaire 双向BFS

转载请注明出处,谢谢 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
*/


 

你可能感兴趣的:(struct,iterator,n2)