您的位置:首页 > 其它

HDU-3713:Double Maze(双重BFS)

2017-08-10 20:52 281 查看
题目链接:点击打开链接

题目大意:

有两个迷宫,每个迷宫有自己的起点终点,两个迷宫分别有一个球在起点,你的命令同时对两个球都生效,若其中一个碰到障碍无法移动。若其中一个球掉到洞中或者出边界即为失败。

解题思路:

本质上就是个简单的BFS,状态搞个四维数组存一下,每次依次判断清楚哪个方向有障碍就好,路径用 string储存,因为要最小字典序,所以方向要注意一下。比赛的时候因为读错题,以为其中一个到终点就可以不用管了,导致最终代码异常复杂。本着赛后AC原则,赛后将代码删了些东西就tm过了。唉,以后一定看清楚题目再写题,这次连样例都没看,确实是对自己的蜜汁自信,也毁了自己。

本题唯一复杂的地方就是每个点的性质是用二进制表示的,所以熟悉位运算之后就很容易搞了。细节部分看代码吧,自己代码比较繁琐,毕竟比赛时候写的,Orz,

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#include <functional>
#define rank ra
#define lson rt<<1
#define rson rt<<1|1
#define pb push_back
using namespace std;
typedef long long ll;
int n;
int dx[4]={1,0,0,-1}; //按一定顺序的方向数组
int dy[4]={0,-1,1,0};
int sx1,sy1,sx2,sy2; //分别记录两个图的起点终点
int ex1,ey1,ex2,ey2;
int ma1[7][7]; //用于bfs的两个图
int ma2[7][7];
int ma[22][7][7];
bool vis[7][7][7][7]; //记录是否到达过当前状态
int di[5]={1,0,2,3}; //记录每种方向判断是否有障碍需要向右移几位
struct node
{
int x1,y1,x2,y2; //记录当前状态
string dir;
};
queue<node> que;
string ans;
bool check1(int xx1,int yy1,int xx2,int yy2) //其中任意一个点为洞即不可走
{
int kk1=ma1[xx1][yy1];
int kk2=ma2[xx2][yy2];
if(((kk1>>4)&1)==0||((kk2>>4)&1)==0)
return 1;
return 0;
}
bool vs(int xx1,int yy1,int xx2,int yy2) //不符合情况的情况
{
if(xx1<1||xx1>6||yy1<1||yy1>6||xx2<1||xx2>6||yy2<1||yy2>6||vis[xx1][yy1][xx2][yy2])
return 1;
return 0;
}
char vc(int i)
{
if(i==0) return 'D';
if(i==1) return 'L';
if(i==2) return 'R';
return 'U';
}
void bfs()
{
node st;
memset(vis,0,sizeof(vis));
while(!que.empty())
que.pop();
st.x1=sx1;st.y1=sy1;
st.x2=sx2;st.y2=sy2;
vis[st.x1][st.y1][st.x2][st.y2]=1;
que.push(st);
int flag=0;
while(!que.empty())
{
node k=que.front();
que.pop();
if(k.x1==ex1&&k.x2==ex2&&k.y1==ey1&&k.y2==ey2) //都到达终点就结束
{
flag=1;
ans=k.dir;

9c18
break;
}
int kk1=ma1[k.x1][k.y1];
int kk2=ma2[k.x2][k.y2];
for(int i=0;i<4;i++)
{
int xx1=k.x1;
int yy1=k.y1;
int xx2=k.x2;
int yy2=k.y2;
if(((kk1>>di[i])&1)==0) //判断当前方向是否有障碍
{
xx1=k.x1+dx[i];
yy1=k.y1+dy[i];
}
if(((kk2>>di[i])&1)==0) //同上
{
xx2=k.x2+dx[i];
yy2=k.y2+dy[i];
}
if(check1(xx1,yy1,xx2,yy2)||vs(xx1,yy1,xx2,yy2)) //不符合情况跳过
continue ;
node sk;
sk.x1=xx1;sk.y1=yy1;
sk.x2=xx2;sk.y2=yy2;
sk.dir=k.dir+vc(i);
vis[xx1][yy1][xx2][yy2]=1;
que.push(sk);
}
}
if(flag==0)
ans="-1";
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int k=1;k<=n;k++)
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
scanf("%d",&ma[k][i][j]); //记录所有地图
for(int k=1;k<n;k++) //依次赋给两个地图
{
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
ma1[i][j]=ma[k][i][j];
int k=ma1[i][j];
if((k>>5)&1) //找起点
{
sx1=i;
sy1=j;
}
if((k>>6)&1) //找终点
{
ex1=i;
ey1=j;
}
}
}
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
ma2[i][j]=ma[k+1][i][j];
int k=ma2[i][j];
if((k>>5)&1)
{
sx2=i;
sy2=j;
}
if((k>>6)&1)
{
ex2=i;
ey2=j;
}
}
}
bfs(); //进行bfs过程
cout<<ans<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: