码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1401 Solitaire (双向广搜)

时间:2014-06-22 20:00:14      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   get   2014   


题意:在二维8*8的方格,给定4个初始点和4个最终点,问在8步内是否能从初始点走到最终点,


规则:每个点能上下左右移动,若4个方向已经有点则可以跳到下一个点。

双向广搜:同时对初始点和最终点广搜4步,对每一步记录状态,初始点为‘1’,最终点为‘2’,

若在限定时间内初始点的状态能到达‘2’,或最终点的状态能到达‘1’,则为YES!要记得排序。。


#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;

struct point 
{
	int x,y;
	bool check()
	{
		if(x<8&&x>=0&&y>=0&&y<8)
			return true;
		return false;
	}
};
struct node
{
	point p[4];
	int step;
}s,e;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int mat[10][10];
bool cmp(point a,point b)//排序
{
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}
void make_map(node a)//标记4个点的位置
{
	mat[a.p[0].x][a.p[0].y]=1;
	mat[a.p[1].x][a.p[1].y]=1;
	mat[a.p[2].x][a.p[2].y]=1;
	mat[a.p[3].x][a.p[3].y]=1;
}
int IsOk(point a)
{
	if(mat[a.x][a.y])
		return 1;
	return 0;
}
char vis[8][8][8][8][8][8][8][8];
void make_vis(node a,char w)//标记状态
{
	vis[a.p[0].x][a.p[0].y][a.p[1].x][a.p[1].y][a.p[2].x][a.p[2].y][a.p[3].x][a.p[3].y]=w;
}
char get_vis(node a)//获得状态
{
	return vis[a.p[0].x][a.p[0].y][a.p[1].x][a.p[1].y][a.p[2].x][a.p[2].y][a.p[3].x][a.p[3].y];
}
bool bfs()
{
	node u,v;
	memset(vis,0,sizeof(vis));
	make_vis(s,'1');
	make_vis(e,'2');
	s.step=0;
	e.step=0;
	queue<node>q,t;
	q.push(s);
	t.push(e);
	while(!q.empty()||!t.empty())
	{
		if(!q.empty())
		{
			u=q.front();
			q.pop();
			memset(mat,0,sizeof(mat));
			make_map(u);
			if(u.step>=4)
				continue;
			for(int i=0;i<4;i++)
			{
				for(int j=0;j<4;j++)
				{
					v=u;
					v.step++;
					v.p[j].x+=dir[i][0];
					v.p[j].y+=dir[i][1];
					if(!v.p[j].check())
						continue;
					if(IsOk(v.p[j]))//跳步
					{
						v.p[j].x+=dir[i][0];
						v.p[j].y+=dir[i][1];
						if(!v.p[j].check())
							continue;
					}
					sort(v.p,v.p+4,cmp);
					if(get_vis(v)=='1') continue;
					else if(get_vis(v)=='2') return true;//可以到达终点
					make_vis(v,'1');
					q.push(v);
				}
			}
		}
		if(!t.empty())
		{
			u=t.front();
			t.pop();
			memset(mat,0,sizeof(mat));
			make_map(u);
			if(u.step>=4)
				continue;
			if(get_vis(u)=='1')
				return true;
			for(int i=0;i<4;i++)
			{
				for(int j=0;j<4;j++)
				{
					v=u;
					v.step++;
					v.p[j].x+=dir[i][0];
					v.p[j].y+=dir[i][1];
					if(!v.p[j].check())
						continue;
					if(IsOk(v.p[j]))
					{
						v.p[j].x+=dir[i][0];
						v.p[j].y+=dir[i][1];
						if(!v.p[j].check())
							continue;
					}
					sort(v.p,v.p+4,cmp);
					if(get_vis(v)=='1') return true;
					else if(get_vis(v)=='2') continue;
					make_vis(v,'2');
					t.push(v);
				}
			}
		}
	}
	return false;
}
int main()
{
	while(~scanf("%d%d",&s.p[0].x,&s.p[0].y))
	{
		for(int i=1;i<4;i++)
			scanf("%d%d",&s.p[i].x,&s.p[i].y);
		for(int i=0;i<4;i++)
			scanf("%d%d",&e.p[i].x,&e.p[i].y);
		for(int i=0;i<4;i++)
		{
			s.p[i].x--;s.p[i].y--;
			e.p[i].x--;e.p[i].y--;
		}
		sort(s.p,s.p+4,cmp);
		sort(e.p,e.p+4,cmp);
		bfs()?puts("YES"):puts("NO");
	}
	return 0;
}


HDU 1401 Solitaire (双向广搜),布布扣,bubuko.com

HDU 1401 Solitaire (双向广搜)

标签:style   class   blog   code   get   2014   

原文地址:http://blog.csdn.net/u012861385/article/details/32714671

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!