zoukankan      html  css  js  c++  java
  • BFS+状态压缩 hdu-1885-Key Task

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1885

    题目意思:

    给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应颜色的钥匙才能打开,问到达终点的最短步数。

    解题思路:

    BFS+状态压缩。

    将每种颜色对应一个二进制数位,1表示已经得到该颜色的钥匙,0表示没有得到。

    一把钥匙可以同种颜色的多扇门。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF 0x1f1f1f1f
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    
    map<char,int>myp1,myp2;
    
    bool vis[20][110][110];
    char save[110][110];
    int n,m,dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
    
    struct Point
    {
       int x,y,step,ss;
    }s;
    
    bool iscan(int x,int y)
    {
       if(x<1||x>n||y<1||y>m||save[x][y]=='#')
          return false;
       return true;
    }
    //一把钥匙可以开颜色相同的多种锁
    void bfs()
    {
       memset(vis,false,sizeof(vis));
       s.step=0,s.ss=0;
       queue<Point>myq;
    
       myq.push(s);
       vis[0][s.x][s.y]=true;
       while(!myq.empty())
       {
          Point tmp=myq.front();
          myq.pop();
    
          int xx,yy;
    
          for(int i=0;i<4;i++)
          {
             xx=tmp.x+dir[i][0],yy=tmp.y+dir[i][1];
             if(!iscan(xx,yy))
                continue;
             if(save[xx][yy]=='X')
             {
                printf("Escape possible in %d steps.
    ",tmp.step+1);
                return ;
             }
    
             int tt=tmp.ss;
             if(myp1.find(save[xx][yy])!=myp1.end()) //得到一把钥匙
             {
                tt=tt|(1<<myp1[save[xx][yy]]);
                if(vis[tt][xx][yy]) //该状态之前已被访问
                   continue;
             }
             else if(myp2.find(save[xx][yy])!=myp2.end())
             {
                if(!(tt&(1<<myp2[save[xx][yy]]))) //没有钥匙
                   continue;
             }
             if(vis[tt][xx][yy])
                continue;
             vis[tt][xx][yy]=true;
             Point t;
             t.x=xx,t.y=yy,t.ss=tt,t.step=tmp.step+1;
             myq.push(t);
          }
       }
       printf("The poor student is trapped!
    ");
       return ;
    }
    
    int main()
    {
       myp1['b']=0,myp1['y']=1,myp1['r']=2,myp1['g']=3; //每种不同的颜色对应不同的数位
       myp2['B']=0,myp2['Y']=1,myp2['R']=2,myp2['G']=3;
    
       while(scanf("%d%d",&n,&m)&&m+n)
       {
          memset(vis,false,sizeof(vis));
          for(int i=1;i<=n;i++)
          {
             scanf("%s",save[i]+1);
             for(int j=1;j<=m;j++)
             {
                if(save[i][j]=='*')
                   s.x=i,s.y=j;
             }
          }
          bfs();
       }
    
       return 0;
    }
    
    
    
    


  • 相关阅读:
    C语言(十八)综合
    C语言(十七)链表
    Redis使用
    fastdb 使用
    CentOS 7.3 安装Oracle 11gR2 64位
    VMWare 12 安装CentOS 7.3 和 Red Hat Enterprise Linux 7.3
    Python学习
    Debian的软件包管理工具命令 (dpkg,apt-get)详解
    Debian8安装Vim8
    VMware12下安装Debian8.5
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3235475.html
Copyright © 2011-2022 走看看