您的位置:首页 > 大数据 > 人工智能

hdu 1401 Solitaire (双向广搜)

2012-02-23 19:54 267 查看
题意:在8 * 8 的跳棋棋盘上,给你两个状态,每个状态4个点,判断一个状态8步内能否到达另一个状态。

分析:给定了始末状态,很典型的双向广搜。

从始末两个方向进行广度搜索,理想情况下可以减少二分之一的搜索量,从而提高搜索速度。

问题的关键在于状态的保存,因为四个棋子是一样的,棋盘的大小只有8*8,所以先按坐标排序之后,用二进制每三个位保存一个棋子的一个坐标,总共需要24个位。

对双向广度搜索算法改进:

略微修改一下控制结构,每次while循环时只扩展正反两个方向中节点数目较少的一个,可以使两边发展速度保持一定的平衡,从而减少总扩展节点个数,加快搜索速度。

这代码写的有点挫,用俩个BFS写的,不是用同一个的,不过也省了麻烦,第一道双广,调试了一个下午。

View Code

#include<iostream>
#include<algorithm>
#include<queue>
#include<bitset>
#define N 8
using namespace std;
bitset<20000010> vis1,vis2;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool map

,flag;
struct point
{
int x,y;
};
struct node
{
point p[4];
};
node start,end1;
queue<node> Q1,Q2;
bool cmp(point a,point b)
{
if(a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
void get_map(point p[])
{
memset(map,0,sizeof(map));
for(int i=0;i<4;i++)
map[p[i].x][p[i].y]=1;
}
int get_hash(point p[])
{
sort(p,p+4,cmp);
int a=0,j=7;
for(int i=0;i<4;i++)
{
a|=(p[i].x<<(j*3));
a|=(p[i].y<<(j-1)*3);
j-=2;
}
return a;
}
void BFS1()
{
int a;
int size=Q1.size();
while(size--)
{
node q=Q1.front(),temp;
Q1.pop();
get_map(q.p);
for(int i=0;i<4;i++)
for(int k=0;k<4;k++)
{
temp=q;
int x=q.p[i].x+dir[k][0];
int y=q.p[i].y+dir[k][1];
if(x<0 ||x>=N || y<0 || y>=N)
continue;
temp.p[i].x=x;
temp.p[i].y=y;
if(map[x][y])
{
int x1=x+dir[k][0];
int y1=y+dir[k][1];
if(x1<0 || x1>=N || y1<0 || y1>=N || map[x1][y1])
continue;
temp.p[i].x=x1;temp.p[i].y=y1;
}
a=get_hash(temp.p);
if(vis1[a]) continue;
if(vis2[a]) {
flag=true;
return ;
}
vis1[a]=true;
Q1.push(temp);
}
}
}
void BFS2()
{
int a;
int size=Q2.size();
while(size--)
{
node q=Q2.front(),temp;
Q2.pop();
get_map(q.p);
for(int i=0;i<4;i++)
for(int k=0;k<4;k++)
{
temp=q;
int x=temp.p[i].x+dir[k][0];
int y=temp.p[i].y+dir[k][1];
if(x<0 ||x>=N || y<0 || y>=N)
continue;
temp.p[i].x=x;
temp.p[i].y=y;
if(map[x][y])
{
int x1=x+dir[k][0];
int y1=y+dir[k][1];
if(x1<0 || x1>=N || y1<0 || y1>=N || map[x1][y1])
continue;
temp.p[i].x=x1;temp.p[i].y=y1;
}
a=get_hash(temp.p);
if(vis2[a]) continue;
if(vis1[a]) {
flag=true; return ;
}
vis2[a]=true;
Q2.push(temp);
}
}
}
int main()
{
while(scanf("%d %d",&start.p[0].x,&start.p[0].y)==2)
{
start.p[0].x--;
start.p[0].y--;
for(int i=1;i<4;i++)
{
scanf("%d %d",&start.p[i].x,&start.p[i].y);
start.p[i].x--;start.p[i].y--;
}
for(int i=0;i<4;i++)
{
scanf("%d %d",&end1.p[i].x,&end1.p[i].y);
end1.p[i].x--;
end1.p[i].y--;
}
while(!Q1.empty())
Q1.pop();
while(!Q2.empty())
Q2.pop();
vis1.reset();
vis2.reset();
int a;
a=get_hash(start.p);
vis1[a]=true;
int b=get_hash(end1.p);
if(a==b) {
printf("YES\n");
continue;
}
vis2[b]=true;
Q1.push(start);Q2.push(end1);
int step=8;
flag=false;
while(step--)
{
if(Q1.size()<=Q2.size())
BFS1();
else BFS2();
if(flag) break;
}
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: