HDU 1885 Key Task

Key Task

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2289    Accepted Submission(s): 1005


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
     

    Recommend
    linle

    题意:4钥匙4种门,一类钥匙可以开这一类所有的门,求到达终点的最小步数
    刚开始是想创建一个六维数组保存没一种钥匙的状态,但是明显超内存了,自己还是太水了,= =,后来看别人的博客才知道要用到状态压缩,以这一题为例,有四种钥匙,每把钥匙的数量不是重点,如果用一个2^4的数保存即可,先将每种钥匙分别赋值为0,1,2,3,从0000到1111一共有16种状态,每种状态不会重合,例如1110就可以表示现在有3,2,1种钥匙。

    #pragma comment(STACK/linker,"102400000,102400000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<set>
    #include<stack>
    #include<deque>
    
    using namespace std;
    
    typedef long long ll;
    
    #define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
    #define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
    #define mem(i,a) memset(i,a,sizeof i)
    #define sf scanf
    #define pf printf
    
    char g[101][101];
    int m,n,i,j,k,x1,y1;
    bool vis[101][101][110];
    const int dx[]={0,0,1,-1};
    const int dy[]={1,-1,0,0};
    char g1[]={'b','r','y','g'};//将钥匙赋值
    char g2[]={'B','R','Y','G'};//将门赋值
    
    struct Node
    {
        int x,y,t,k;
        Node(){}
    }que[100010];
    
    void solve()
    {
        Node tmp,p;
        int s,e;
        s=e=0;
        tmp.x=x1,tmp.y=y1,tmp.t=0,tmp.k=0;
        vis[tmp.x][tmp.y][tmp.k]=1;
        que[e++]=tmp;
        while(s<e)
        {
            tmp=que[s++];
            for0(i,4)
            {
                p=tmp;
                p.x+=dx[i],p.y+=dy[i],p.t++;
                if(p.x<1||p.x>m||p.y<1||p.y>n||g[p.x][p.y]=='#')
                    continue;
                if(g[p.x][p.y]=='X')
                {
                    pf("Escape possible in %d steps.\n",p.t);
                    return ;
                }
                if(g[p.x][p.y]>'A'&&g[p.x][p.y]<'Z')//如果遇到门,就用保存钥匙状态的数对其移位做按位与运算,如果不为0就表示有这种钥匙
                {
                    for(j=0;j<4;j++)
                        if(g[p.x][p.y]==g2[j])
                            if(p.k&(1<<j))
                                if(!vis[p.x][p.y][p.k])
                                    vis[p.x][p.y][p.k]=1,que[e++]=p;
                }
                else if(g[p.x][p.y]>'a'&&g[p.x][p.y]<'z')//如果遇到钥匙,就将当前保存钥匙状态的数更新
                {
                    for(j=0;j<4;j++)
                        if(g[p.x][p.y]==g1[j])
                        {
                            p.k=p.k|(1<<j);
                            if(!vis[p.x][p.y][p.k])
                                vis[p.x][p.y][p.k]=1,que[e++]=p;
                        }
                }
                else if(!vis[p.x][p.y][p.k])
                    vis[p.x][p.y][p.k]=1,que[e++]=p;
            }
        }
        pf("The poor student is trapped!\n");
    }
    
    int main()
    {
        while(sf("%d%d",&m,&n),m+n)
        {
            mem(vis,0);
            for1(i,m)
                for1(j,n)
                {
                    cin>>g[i][j];
                    if(g[i][j]=='*')
                        vis[i][j][0]=1,x1=i,y1=j;
                }
            solve();
        }
        return 0;
    }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值