HDU1429:胜利大逃亡(续)

传送门

题意

给出一个迷宫,门需要钥匙来打开,t秒内能否从起点到达终点

分析

这题我用以前一道题的代码改了改就过了,具体思想:设置vis[status][x][y],status记录到达该点拥有的钥匙,每次更新,这样可以保证最短

trick

代码

/*
每个点在拥有相同钥匙(状态)下都只走一遍,这样可以最短
*/
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
#define cpy(a,b) memcpy(a,b,sizeof(b))
#pragma comment(linker, "/STACK:102400000,102400000")
inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}

int n,m,ans,t;
char s[25][25];
bool vis[2048][25][25];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
struct node
{
    int x,y,status,time;
    node(){}
    node(int xx,int yy,int s,int t)
    {
        x=xx,y=yy,status=s,time=t;
    }
}tmp,p;
int bfs(int sx,int sy)
{
    mem(vis,0);
    queue<node>q;
    p={sx,sy,0,0};
    q.push(p);
    while(!q.empty())
    {
        tmp=q.front();
        q.pop();
        for(int i=0;i<4;++i)
        {
            int x=tmp.x+dir[i][0],y=tmp.y+dir[i][1],status=tmp.status,time=tmp.time;
            if(x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='*'&&!vis[status][x][y])
            {
                if(s[x][y]>='A'&&s[x][y]<='J')
                {
                    int ret=s[x][y]-'A';
                    if(status&(1<<ret))
                    {
                        vis[status][x][y]=1;
                        q.push(node(x,y,status,time+1));
                    }
                }
                else if(s[x][y]>='a'&&s[x][y]<='j')
                {
                    int ret=s[x][y]-'a';
                    status|=(1<<ret);
                    vis[status][x][y]=1;
                    q.push(node(x,y,status,time+1));
                }
                else if(s[x][y]=='.')
                {
                    vis[status][x][y]=1;
                    q.push(node(x,y,status,time+1));
                }
                else if(s[x][y]=='^') return time+1;
            }
        }
    }
    return -1;
}
int main()
{
    int sx,sy;
    while(scanf("%d %d %d",&n,&m,&t)==3)
    {
        R(i,0,n)
        {
            scanf("%s",&s[i]);
            R(j,0,m) if(s[i][j]=='@') { sx=i;sy=j;s[i][j]='.'; break; }
        }
        ans=bfs(sx,sy);
        if(ans==-1||ans>=t) puts("-1");else printf("%d\n",ans);
    }
    return 0;
}
posted @ 2017-04-07 09:15  遗风忘语  阅读(146)  评论(0编辑  收藏  举报