HDU 1885 BFS+状态压缩

Key Task

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1239    Accepted Submission(s): 495

Problem Description

The Czech Technical University is rather old — you already know that it celebrates 300 years of its existence in 2007. Some of the university buildings are old as well. And the navigation in old buildings can sometimes be a little
bit tricky, because of strange long corridors that fork and join at absolutely unexpected places.

The result is that some first-graders have often di?culties finding the right way to their classes. Therefore, the Student Union has developed a computer game to help the students to practice their orientation skills. The goal of the game is to find the way
out of a labyrinth. Your task is to write a verification software that solves this game.

The labyrinth is a 2-dimensional grid of squares, each square is either free or filled with a wall. Some of the free squares may contain doors or keys. There are four di?erent types of keys and doors: blue, yellow, red, and green. Each key can open only doors
of the same color.

You can move between adjacent free squares vertically or horizontally, diagonal movement is not allowed. You may not go across walls and you cannot leave the labyrinth area. If a square contains a door, you may go there only if you have stepped on a square
with an appropriate key before.

Input

The input consists of several maps. Each map begins with a line containing two integer numbers R and C (1 ≤ R, C ≤ 100) specifying the map size. Then there are R lines each containing C characters. Each character is one of the following:

Note that it is allowed to have

  • more than one exit,
  • no exit at all,
  • more doors and/or keys of the same color, and
  • keys without corresponding doors and vice versa.

    You may assume that the marker of your position (“*”) will appear exactly once in every map.

    There is one blank line after each map. The input is terminated by two zeros in place of the map size.

  • Output

    For each map, print one line containing the sentence “Escape possible in S steps.”, where S is the smallest possible number of step to reach any of the exits. If no exit can be reached, output the string “The poor student is trapped!”
    instead.

    One step is defined as a movement between two adjacent cells. Grabbing a key or unlocking a door does not count as a step.

    Sample Input

    1 10
    *........X
    
    1 3
    *#X
    
    3 20
    ####################
    #XY.gBr.*.Rb.G.GG.y#
    ####################
    
    0 0
    

    Sample Output

    Escape possible in 9 steps.
    The poor student is trapped!
    Escape possible in 45 steps.
    

    Source

    2008 “Shun Yu Cup” Zhejiang Collegiate
    Programming Contest - Warm Up(2)

    /*************************************************************************
    	> File Name: 3.cpp
    	> Author:yuan
    	> Mail:
    	> Created Time: 2014年11月26日 星期三 13时09分34秒
     ************************************************************************/
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char mat[105][105];
    int ans;
    struct node
    {
        int x,y;
        int num,key;
    };
    bool vis[105][105][30];
    queue<node> q;
    int sx,sy;
    int n,m,top,base;
    int next[4][2]={1,0,0,1,-1,0,0,-1};
    
    void BFS()
    {
        int x1,x2,y1,y2;node p,qq;
        while(!q.empty()){
         p=q.front();
          x1=p.x;y1=p.y;
            if(mat[x1][y1]=='X'){
                ans=p.num;
                return;
            }
            for(int i=0;i<4;i++)
            {
                int key;
                x2=x1+next[i][0];y2=y1+next[i][1];
                if(x2<0||x2>=n||y2<0||y2>=m||mat[x2][y2]=='#') continue;
    
                if(mat[x2][y2]=='.'||mat[x2][y2]=='*'||mat[x2][y2]=='X')
                {
                    key=p.key;
                    if(vis[x2][y2][key]==0)
                    {
                        qq.x=x2;qq.y=y2;qq.num=p.num+1;qq.key=p.key;
                        q.push(qq);
                        vis[x2][y2][key]=1;
                    }
                }
    
                 else if(mat[x2][y2]=='B'||mat[x2][y2]=='Y'||mat[x2][y2]=='R'||mat[x2][y2]=='G')
                  {
                    key=p.key;
                    if(vis[x2][y2][key]==0){
                        int d;
                        if(mat[x2][y2]=='B') d=0;
                        else  if(mat[x2][y2]=='Y') d=1;
                               else  if(mat[x2][y2]=='R') d=2;
                                      else  if(mat[x2][y2]=='G') d=3;
                        int lock=1<<d;
                        if(lock&key){
                             qq.x=x2;qq.y=y2;qq.num=p.num+1;qq.key=p.key;
                             q.push(qq);
                             vis[x2][y2][key]=1;
                        }
                    }
                }
                else if(mat[x2][y2]=='b'||mat[x2][y2]=='y'||mat[x2][y2]=='r'||mat[x2][y2]=='g')
                {
                      int d;
                        if(mat[x2][y2]=='b') d=0;
                        else  if(mat[x2][y2]=='y') d=1;
                               else  if(mat[x2][y2]=='r') d=2;
                                      else  if(mat[x2][y2]=='g') d=3;
                    key=1<<d;
                    if(vis[x2][y2][p.key]==0){
                        qq.x=x2;qq.y=y2;qq.num=p.num+1;qq.key=p.key|key;
                        q.push(qq);
                        vis[x2][y2][p.key]=1;
                    }
                }
            }
          q.pop();
        }
    }
    int main()
    {
         while(1){
            scanf("%d%d",&n,&m);
            if(n==0&&m==0) break;
            memset(mat,0,sizeof(mat));
            memset(vis,0,sizeof(vis));
            while(!q.empty()) q.pop();
            for(int i=0;i<n;i++) scanf("%s",mat[i]);
            for(int i=0;i<n;i++)
              for(int j=0;j<m;j++)
            {
                if(mat[i][j]=='*') {sx=i,sy=j;}
    
            }
            node p;
            p.x=sx;p.y=sy;p.num=0;p.key=0;
            q.push(p);
            vis[sx][sy][0]=1;
            ans=100000000;
            BFS();
            if(ans<100000000) printf("Escape possible in %d steps.\n",ans);
            else printf("The poor student is trapped!\n");
        }
        return 0;
    }
    
    时间: 2024-10-10 16:35:42

    HDU 1885 BFS+状态压缩的相关文章

    hdu 3502 bfs+状态压缩dp

    题意是给你n*m的矩阵     每个单位有一个数,-1表示不能走   >=0表示有有多少个能量能获得    问从左上角到右下角能获得的做大能量值(走一步消耗1单位能量) 思路:  先bfs求出所有线之间的最短距离(当然  有用的只有有能量值的点和起点,终点) 然后状态压缩dp  找到最大能量值    这里有几个注意的地方 状态尽量从1开始    减少数组的空间(爆了一次)   其次是bfs是只搜有能量的点     其它都差不多: #include<stdio.h> #include<

    hdu 1429(BFS+状态压缩)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7895    Accepted Submission(s): 2795 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这 次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了

    hdu 4856 Tunnels(bfs+状态压缩)

    题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,现在有人想要体验下这M个管道,问最短需要移动的距离,起点未定. 解题思路:首先用bfs处理出两两管道之间移动的距离,然后后用状态压缩求出最短代价,dp[i][j],i表示的已经走过的管道,j是当前所在的管道. #include <cstdio> #include <cstring> #include <queue> #include <algorithm&g

    HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP 用最短路预处理出状态的转移.能够优化非常多 AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <queue> us

    HDU 3247 Resource Archiver (AC自动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串,m个病毒串,问包含所有正常串(可重叠)且不包含任何病毒串的字符串的最小长度为多少. AC自动机 + bfs + 状态压缩DP 用最短路预处理出状态的转移.可以优化很多 AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <queue> using n

    hdu 4568(状态压缩dp)

    题意:一张n*m的网格内每个点有话费,还有若干个宝藏,问一个人要走进去拿走所有宝藏在走出来的最小花费. 思路:看宝藏只有13个直接想到了状压dp[i][j]拿了哪几个前一个为j的最小花费,先bfs+优先队列预处理出最短路,然后记忆化搜索就可. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao

    hdu--1429--胜利大逃亡(续) (bfs+状态压缩)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8560    Accepted Submission(s): 3071 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

    ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

    求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其到(1,1)的最短路长 题解:开始做的时候用BFS暴力做了一次,结果RE了,后来看了其他的题解和discuss才转向状态压缩.也看到有人用A*做出来了. 现在简要介绍一下状态压缩的思路: 由于蛇身最长只有8,可以利用两条相邻蛇身坐标确定其相对方向(四个方向),两位二进制可以表示 这样 一个蛇头坐标+

    hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 901    Accepted Submission(s): 314 Problem Description This story happened on the background of Star Trek. Spock, the deputy captain of St