hdu 5094 Maze(水搜索)

  题目意思:说有一个人在(1,1) 他的目标点在(n,m) 每次是4方向的移动;

      限制条件:有的各自之间有墙 或者门,强不可通过,有对应的要钥匙可以开启这个类型的所有门;

      问题:求最少步骤数(和)

  类似于poj 2935;

    解:很明显的搜索 只要建图弄得好就非常好写:我还是 很推荐自己的建图 方法,不经常建图的可以看一看:(特别是 一个地方可以有多种钥匙,一开始我就Wa了)

  

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
const int maxn=50*50*(1<<10)+10;
bool flag[50][50][(1<<10)+10];
struct info
{
    int x,y,S,ans;
    info (){}
    info(int x,int y,int S,int ans):x(x),y(y),S(S),ans(ans){}
    void input()
    {
        scanf("%d%d",&x,&y);
    }
    void FLAG()
    {
        flag[x][y][S]=true;
    }
};
int n,m,p;
int Map[51][51];
int direct[51][51][4];
info que[maxn];
const int dd[][2]={1,0,-1,0  ,0,-1,0,1};
bool jude(int & x,int & y)
{
    return x>=1&&y>=1&&x<=n&&y<=m;
}
void inint()
{
    memset(direct,0,sizeof direct);
    memset(Map,0,sizeof Map);
    memset(flag,false,sizeof flag);
}
void  work()
{
    info  a,b;
    a.input();b.input();
    int key;
    scanf("%d",&key);
    for(int  i=0;i<4;i++)
    {
        if((a.x+dd[i][0]==b.x) && (a.y+dd[i][1]==b.y))
        {
            direct[a.x][a.y][i]=  (key==0 ? -1:key);
            direct[b.x][b.y][i^1]=(key==0 ? -1:key);
            break;
        }
    }

}
bool ok(const info & tmp,const int &i)
{
    if(direct[tmp.x][tmp.y][i] ==  0) return true;
    if(direct[tmp.x][tmp.y][i] == -1) return false;
    return ( 1<<(direct[tmp.x][tmp.y][i]-1) ) & tmp.S;
}
int solve()
{
    int l,r;l=r=0;
    que[r++]=info(1,1,Map[1][1],0);
    while(l<r)
    {
        info tmp=que[l++];
        if(tmp.x==n&&tmp.y==m) return tmp.ans;
        for(int i=0;i<4;i++)
        {
            if( !ok(tmp,i) ) continue;
            int x=tmp.x+dd[i][0];
            int y=tmp.y+dd[i][1];
            if(!jude(x,y)) continue;

            info t=info(x,y ,tmp.S|Map[x][y],tmp.ans+1);

            if(!flag[x][y][t.S])
            {
                que[r++]=t;
                t.FLAG();
                if(t.x==n&&t.y==m) return t.ans;
            }
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d%d",&n,&m,&p))
    {
        inint();
        scanf("%d",&p);
        for(int i=1;i<=p;i++) work();
        scanf("%d",&p);
        for(int i=1;i<=p;i++){
            int x,y,key;
            scanf("%d%d%d",&x,&y,&key);
            Map[x][y]|=(1<<(key-1));
        }
        printf("%d\n",solve());
    }
    return 0;
}

 

posted @ 2014-11-03 12:05  默默无语敲代码  阅读(402)  评论(0编辑  收藏  举报