1885Key Task(BFS+状态压缩)(胜利大逃亡续)一个意思

Key Task

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

Total Submission(s): 1229    Accepted Submission(s): 493

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.
    

    每个格子都有不同的状态,关键是在判断在走到当前格子的当前key状态是否走过。

    #include<stdio.h>
    #include<queue>
    #include<iostream>
    #include<string.h>
    using namespace std;
    #define N 105
    struct locate
    {
        int x,y,step,state;
    };
    char map[N][N];
    int state[N][N][16],n,m;
    
    int BFS(int sx,int sy)
    {
        queue<locate>q;
        locate p,tp;
        int dir[4][2]={0,1,1,0,0,-1,-1,0};
        char door[6]={"BYRG"},key[6]={"byrg"};
    
        memset(state,0,sizeof(state));
        p.step=0; p.state=0;
        p.x=sx; p.y=sy;
        q.push(p); state[sx][sy][0]=1;
    
        while(!q.empty())
        {
            p=q.front(); q.pop();
            for(int e = 0;e < 4;++e)
            {
                tp.x=p.x+dir[e][0];
                tp.y=p.y+dir[e][1];
    
                if(tp.x>=0&&tp.x<n&&tp.y>=0&&tp.y<m&&map[tp.x][tp.y]!='#'&&!state[tp.x][tp.y][p.state])
                {
                    tp.step=p.step+1;
                    tp.state=p.state;
                    if(map[tp.x][tp.y]=='X')
                        return tp.step;
                    int flag=0;
                    for(int i=0;i<4;i++)
                        if(map[tp.x][tp.y]==key[i])
                        {
                            flag=1; tp.state|=(1<<i);break;
                        }
                    state[tp.x][tp.y][tp.state]=1;
                    if(!flag)
                    {
                        flag=0;
                        for(int i=0;i<4;i++)
                            if(map[tp.x][tp.y]==door[i])
                            {
                                flag=1;
                                if(tp.state&(1<<i))
                                    flag=2;
                                break;
                            }
                        if(flag!=1)
                            q.push(tp);
                    }
                    else
                        q.push(tp);
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        int sx,sy;
        while(scanf("%d%d",&n,&m)>0)
        {
            if(n==0&&m==0)
                break;
            for(int i=0;i<n;i++)
                scanf("%s",map[i]);
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                if(map[i][j]=='*')
                sx=i,sy=j;
            int ans=BFS(sx,sy);
            if(ans)
                printf("Escape possible in %d steps.\n",ans);
            else
                printf("The poor student is trapped!\n");
        }
    }
    
    时间: 2024-10-11 05:05:56

    1885Key Task(BFS+状态压缩)(胜利大逃亡续)一个意思的相关文章

    HDU 1885Key Task(bfs + 状态压缩)

    Key Task Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1529 Accepted Submission(s): 631 Problem Description The Czech Technical University is rather old - you already know that it celebrates 300

    胜利大逃亡(续)(状态压缩bfs)

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

    hdoj 1429 胜利大逃亡(续) 【BFS+状态压缩】

    题目:hdoj 1429 胜利大逃亡(续) 相同题目: 题意:中文的,自己看 分析:题目是求最少的逃亡时间,确定用BFS 这个题目的难点在于有几个锁对于几把钥匙,唯一的对应关系,不能用直接的标记法,因为一个图可能需要搜索多次. 仔细分析的话会发现,图的搜索次数是和钥匙的出现次数相关,那么我们可以用二进制的0 和 1 来表示第几把钥匙出现过没有,所以我们可以用状态压缩来标记那个钥匙出现过,然后用三维标记,第三维表示出现几个钥匙了的情况下图的点的搜索情况.其他就和简单的一样. AC代码: #incl

    hdu1429胜利大逃亡(续) (状态压缩+BFS)

    Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方.刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置.Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个.魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去.经过若干次的尝试,Ignatius已画

    hdu1429胜利大逃亡(续)(状态压缩+bfs)

    题目链接: 啊哈哈,点我点我 题意及思路 最开始我以为跟普通的bfs一样,所以直接写了一个朴素的bfs,一跑,前两组数据对了,但是第三组不对,一看,走过的还可以走啊,所以不能标记,结果我的bfs乱改,最后 毫无疑问改成了死循环.所以看题解... 思路:因为有10中不同的钥匙,每种都有两种状态,所以结合计算机是二进制保存的特点,刚好把这10把钥匙当成每一个为,要要1<<10个位保存所有的状态,然后就是模拟捡起钥匙,捡起钥匙就是说明这个位上的数字变成1这个状态,所以自然而然想到了位运算,只要|一下

    HDU 1429 胜利大逃亡(续)(bfs+状态压缩,很经典)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10648    Accepted Submission(s): 3860 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王

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

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

    hdu 1429 胜利大逃亡(续)(bfs+位压缩)

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

    hdu 1429 胜利大逃亡(续)【广度优先搜索+状态压缩】

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

    hdu 1429 胜利大逃亡(续) 搜索+状态压缩,,不错的题。

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