zoukankan      html  css  js  c++  java
  • 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
    ",solve());
        }
        return 0;
    }
  • 相关阅读:
    rsync命令 SCP命令
    Linux 性能分析 工具命令
    ntp时间服务器 时间同步
    Linux 邮件服务
    linux 手工释放内存 高内存 内存回收 方法思路
    LVM 逻辑卷 (logica volume manager)
    Linux 磁盘原理与管理 (分区 挂载)
    linux中查看nginx、apache、php、mysql配置文件路径
    shell脚本 监控ps 不存在则重启
    Shell脚本 一键重启
  • 原文地址:https://www.cnblogs.com/shuly/p/4070881.html
Copyright © 2011-2022 走看看