HDU 1885 Key Task 题解

来源:互联网 发布:足球大师卡卡头像数据 编辑:程序博客网 时间:2024/06/03 22:48

题意

给定一个迷宫,有入口、出口(可能没有也可能有多个)、空地、4种不同颜色的钥匙和门,有了对应的钥匙才可以开对应的门,每一步只能往四连通方向走,问是否能从入口走到出口,如果能走到,最少需要走多少步

思路

bfs,记录位置和钥匙的状态,因为只有4种钥匙的状态,我们就可以用二进制表示了,四个二进制位对应四把不同的钥匙,1表示有,0表示没有,记忆化的时候如果遇到位置重复且钥匙状态一样的就可以不接着这种状态走了

代码

#include <cstdio>#include <iostream>#include <queue>using namespace std;char mp[101][101];typedef struct status{    int x;    int y;    int st;    int step;}status;queue<status> q;bool vis[101][101][16];int main(){    int R,C,ans;    status t;    while(1)    {        cin>>R>>C;        if(R==0&&C==0)            break;        for(int i=0;i<R;i++)            cin>>mp[i];        for(int i=0;i<R;i++)            for(int j=0;j<C;j++)                if(mp[i][j]=='*')                {                    t.x=i;                    t.y=j;                    t.st=0;                    t.step=0;                }        q.push(t);        ans=-1;        while(!q.empty())        {            t=q.front();            if(t.x<0||t.x>=R||t.y<0||t.y>=C||mp[t.x][t.y]=='#'||vis[t.x][t.y][t.st]||(mp[t.x][t.y]=='B'&&(t.st&8)==0)||(mp[t.x][t.y]=='Y'&&(t.st&4)==0)||(mp[t.x][t.y]=='R'&&(t.st&2)==0)||(mp[t.x][t.y]=='G'&&(t.st&1)==0))            {                q.pop();                continue;            }            if(mp[t.x][t.y]=='X')            {                ans=t.step;                break;            }            //cout<<t.x<<" "<<t.y<<" "<<t.st<<" "<<t.step<<endl;            vis[t.x][t.y][t.st]=true;            if(mp[t.x][t.y]=='b')                t.st|=8;            else if(mp[t.x][t.y]=='y')                t.st|=4;            else if(mp[t.x][t.y]=='r')                t.st|=2;            else if(mp[t.x][t.y]=='g')                t.st|=1;            q.pop();            t.step++;            t.x--;            q.push(t);            t.x+=2;            q.push(t);            t.x--;            t.y--;            q.push(t);            t.y+=2;            q.push(t);        }        if(ans!=-1)            cout<<"Escape possible in "<<ans<<" steps."<<endl;        else cout<<"The poor student is trapped!"<<endl;        while(!q.empty())            q.pop();        for(int i=0;i<R;i++)            for(int j=0;j<C;j++)                for(int k=0;k<16;k++)                    vis[i][j][k]=false;    }    return 0;}