HDU 1429:胜利大逃亡(续)
本文最后更新于14 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

最近想写迷宫了,迷宫好玩

HDU 1429:胜利大逃亡(续)

Time Limit: 4000/2000 MS (Java/Others)

Memory Limit: 65536/32768 K (Java/Others)

题目描述

Ignatius 再次被魔王抓走了。这次魔王汲取了上次的教训,把 Ignatius 关在一个 n * m 的地牢里,并在地牢的某些地方安装了带锁的门,而开门的钥匙藏在地牢的其他位置。

  • 刚开始,Ignatius 被关在 (sx, sy) 的位置。
  • 离开地牢的出口在 (ex, ey) 的位置。
  • Ignatius 每分钟只能从当前坐标移动到相邻的四个坐标之一。
  • 魔王每 t 分钟会回地牢视察一次,若发现 Ignatius 不在原位置,便会把他拎回去。

经过若干次尝试,Ignatius 已经画出了整个地牢的地图。现在请你帮他计算能否再次成功逃亡。

逃亡成功判定: 只要在魔王下次视察之前走到出口就算离开地牢。如果魔王回来的时候刚好走到出口,或者还未到出口,均算作逃亡失败。

地图元素说明

地图由以下字符构成:

  • . :代表通路
  • * :代表墙壁(不可通行)
  • @ :代表 Ignatius 的起始位置
  • ^ :代表地牢的出口
  • A-J :代表带锁的门(对应的钥匙分别为 a-j
  • a-j :代表钥匙(对应的门分别为 A-J

输入格式

包含多组测试数据。每组测试数据之间有一个空行。

  1. 每组数据的第一行包含三个整数 n, m, t (2 <= n, m <= 20, t > 0),分别代表地牢的行数、列数以及魔王视察的时间间隔。
  2. 接下来的 n 行,每行包含 m 个字符,表示地牢的地图分布。

输出格式

针对每组测试数据:

  • 如果可以成功逃亡,请输出最少需要多少分钟才能离开。
  • 如果不能逃亡(无法到达出口或超时),则输出 -1

样例输入

4 5 17
@A.B.
a*.*.
*..*^
c..b*

4 5 16
@A.B.
a*.*.
*..*^
c..b*

样例输出

16
-1

思路

状态压缩,因为一共10把钥匙,我们只能用状态压缩,一二维记录坐标,三维存有什么钥匙

理解,状态压缩是为了同时记录多个状态而产生的,状态是有(1),无(0)

代码

// Sunshine, sunshine, ladybugs awake!

// Clap your hooves and do a little shake!

#include <bits/stdc++.h>

#define int long long

#define endl '\n'

using namespace std;

  

using PII=pair<int,int> ;

  

const int mod=666623333;

const int MAXN=25;

  

int dx[4]={0,0,1,-1};

int dy[4]={1,-1,0,0};

bool vis[MAXN][MAXN][2<<10];

char g[MAXN][MAXN];

  

int n,m,k;

struct Node{

    int x,y,key,tim;

};

  

void solve() {  

    memset(vis,false,sizeof(vis));

    int st_x,st_y,ed_x,ed_y;

    for(int i=1;i<=n;i++){

        for(int j=1;j<=m;j++){

            cin>>g[i][j];

            if(g[i][j]=='@'){

                st_x=i;

                st_y=j;

            }

            if(g[i][j]=='^'){

                ed_x=i;

                ed_y=j;

            }

        }

    }

    queue<Node> q;

    q.push({st_x,st_y,0ll,0ll});

    vis[st_x][st_y][0]=true;

    while(!q.empty()){

        auto [x,y,key,t]=q.front();

        q.pop();

        if(t>=k){

            cout<<-1<<endl;

            return  ;

        }

        if(x==ed_x&&y==ed_y){

            cout<<t<<endl;

            return ;

        }

        for(int i=0;i<4;i++){

            int nx=x+dx[i];

            int ny=y+dy[i];

            if(g[nx][ny]=='*')continue;

            if(nx<1||nx>n||ny<1||ny>m)continue;

            int nkey=key;

            if(g[nx][ny]>='A'&&g[nx][ny]<='J'){

                if(!(nkey&(1ll<<(g[nx][ny]-'A')))){

                    continue;

                }

            }

            if(g[nx][ny]>='a'&&g[nx][ny]<='j'){

                nkey|=(1ll<<(g[nx][ny]-'a'));

            }

            if(!vis[nx][ny][nkey]){

                vis[nx][ny][nkey] = true;

                q.push({nx, ny, nkey, t + 1});

            }

        }

    }

    cout << -1 << endl;

}

  

signed main() {

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    //int t;cin >> t;while (t--)

    while(cin>>n>>m>>k) solve();

    return 0;

}
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇