【C++题解】112354.平行时空

题目描述

周末放假回到了家,由于在学校很累,你很快的睡着了,做了一个神奇的梦,梦见你和平行时空的你被困在了一个n行m列的孤岛上。孤岛上含有平地,陷阱和传送门三种不同的地块。你和平行时空的你都可以上下左右移动到相邻的地块中,可是平行时空的你只能同时以相反的方向移动(即你和平行时空的你移动方向相反),两人均不能跨过孤岛的边界,即到达孤岛外的地方,并且任何人到达陷阱处会立即死亡,问你能否找到一个移动序列,使得两个人均能从传送门离开,其中一个人达到传送门后一定会离开孤岛不会再回来。如果你能够找到这样的移动序列,输出该序列的最短长度,否则输出-1。


输入格式

  • 第一行输入四个整数n,m,x,y,表示n行m列的孤岛,初始两人在x行y列的地块中。
  • 接下来n行,每行是一个包含m个字符的字符串,字符串仅包含 .#@ 三种字符,分别表示平地、陷阱和传送门。

数据保证两人初始时所在(x,y)位置是平地。


输出格式

如果能找到两个人离开的路径,输出该路径的最短长度,否则输出-1。

20%的数据保证:1<=n,m<=10

20%的数据保证:1<=n,m<=500

100%的数据保证:1<=n,m<=2e3,1<=x<=n,1<=y<=m


输入/输出例子1

输入:

3 3 2 2

@.@

#..

@.@

输出:

2


输入/输出例子2

输入:

1 3 1 2

..@

输出:

3


样例解释

对于样例二:两人初始在坐标(1,2),第一个人移动到(1,3)到达传送门离开,第二个人此时在(1,1),然后向右移动两次到达(1,3)离开,两人一共移动了3次。


参考答案

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int MAXN = 2005;
struct Node {
    int type, x, y, step;
};
queue<Node> q;
int n, m, sx, sy;
char mp[MAXN][MAXN];

bitset<MAXN> vis0[MAXN];
bitset<MAXN> vis1[MAXN];
bitset<MAXN> vis2[MAXN];

int dir4[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int single_dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int tx, ty;
    cin >> n >> m >> tx >> ty;
    sx = tx - 1;
    sy = ty - 1;
    for (int i = 0; i < n; ++i) {
        cin >> mp[i];
    }
    q.push({0, sx, sy, 0});
    vis0[sx][sy] = 1;
    while (!q.empty()) {
        Node cur = q.front();
        q.pop();
        int t = cur.type;
        int x = cur.x;
        int y = cur.y;
        int st = cur.step;
        if (t == 0) {
            int bx = 2 * sx - x;
            int by = 2 * sy - y;
            for (int d = 0; d < 4; ++d) {
                int dx = dir4[d][0];
                int dy = dir4[d][1];
                int nx = x + dx;
                int ny = y + dy;
                int nbx = bx - dx;
                int nby = by - dy;
                if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                if (nbx < 0 || nbx >= n || nby < 0 || nby >= m) continue;
                if (mp[nx][ny] == '#' || mp[nbx][nby] == '#') continue;
                bool a_gate = (mp[nx][ny] == '@');
                bool b_gate = (mp[nbx][nby] == '@');
                if (a_gate && b_gate) {
                    cout << st + 1 << endl;
                    return 0;
                } else if (a_gate) {
                    if (!vis2[nbx][nby]) {
                        vis2[nbx][nby] = 1;
                        q.push({2, nbx, nby, st + 1});
                    }
                } else if (b_gate) {
                    if (!vis1[nx][ny]) {
                        vis1[nx][ny] = 1;
                        q.push({1, nx, ny, st + 1});
                    }
                } else {
                    if (!vis0[nx][ny]) {
                        vis0[nx][ny] = 1;
                        q.push({0, nx, ny, st + 1});
                    }
                }
            }
        } else if (t == 1) {
            for (int d = 0; d < 4; ++d) {
                int dx = single_dir[d][0];
                int dy = single_dir[d][1];
                int nx = x + dx;
                int ny = y + dy;
                if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                if (mp[nx][ny] == '#') continue;
                if (mp[nx][ny] == '@') {
                    cout << st + 1 << endl;
                    return 0;
                }
                if (!vis1[nx][ny]) {
                    vis1[nx][ny] = 1;
                    q.push({1, nx, ny, st + 1});
                }
            }
        } else {
            for (int d = 0; d < 4; ++d) {
                int dx = single_dir[d][0];
                int dy = single_dir[d][1];
                int nx = x + dx;
                int ny = y + dy;
                if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                if (mp[nx][ny] == '#') continue;
                if (mp[nx][ny] == '@') {
                    cout << st + 1 << endl;
                    return 0;
                }
                if (!vis2[nx][ny]) {
                    vis2[nx][ny] = 1;
                    q.push({2, nx, ny, st + 1});
                }
            }
        }
    }
    cout << -1 << endl;
    return 0;
}
//此题使用vector会超时

题目链接:

https://v1.51goc.com/question/viewProgram/112354

(进去后要登录)

相关推荐
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧6 小时前
C++学习:基础知识的掌握
c++·visualstudio
江畔柳前堤6 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Doraemomo6 小时前
数据结构-环形链表
java·数据结构·链表
Forever Nore7 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考9 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面10 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号10 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI10 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研