HJ161 走一个大整数迷宫

  • 题目
  • 题解(10)
  • 讨论(4)
  • 排行

中等 通过率:40.12% 时间限制:1秒 空间限制:256M

知识点广度优先搜索(BFS)

校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。

描述

给定一个 n×mn×m 的矩阵迷宫,其中第 ii 行第 jj 列的格子权值为

ci,j=ai,j×p2bi,jci,j​=ai,j​×p2bi,j​。

LH 起始位于 (1,1)(1,1),出口位于 (n,m)(n,m)。迷宫配有一个计数器 ,初始值为 c1,1c1,1​。在任意时刻,若计数器的值满足 counter≡0(mod(p−1))counter≡0(mod(p−1)),且 LH 身处出口 (n,m)(n,m),大门即刻打开,LH 得以逃离。

每经过 11 秒,LH 必须向上、下、左、右 四个方向中的某一方向移动一步(不得停留,也不得走出迷宫)。假设 LH 从 (i,j)(i,j) 移动到 (i′,j′)(i′,j′),则计数器会累加 ci′,j′ci′,j′​。

请计算 LH 最快需要多少秒才能逃离;若无论如何都无法逃离,则输出 −1−1。

输入描述:

输入共三部分:

∙ ∙第一行输入三个整数 n,m,p(1≦n,m≦10; 2≦p≦104)n,m,p(1≦n,m≦10; 2≦p≦104);

∙ ∙接下来 nn 行,每行 mm 个整数,构成矩阵 ai,jai,j​;

∙ ∙再接下来 nn 行,每行 mm 个整数,构成矩阵 bi,jbi,j​,范围均为 0≦ai,j,bi,j≦1060≦ai,j​,bi,j​≦106。

输出描述:

输出一个整数,代表最短逃离时间;若无法逃离,输出 −1−1。

示例1

输入:

复制代码
3 3 10
1 2 3
0 1 4
0 0 0
1 0 0
0 0 1
0 1 0

复制输出:

复制代码
6

复制说明:

复制代码
C=[1002030010400000]C=⎣⎡​10000​20100​304000​⎦⎤​。

第一秒,从 (1,1)(1,1) 走到 (1,2)(1,2),计数器的值为 120120。

第二秒,从 (1,2)(1,2) 走到 (1,3)(1,3),计数器的值为 150150。

第三秒,从 (1,3)(1,3) 走到 (1,2)(1,2),计数器的值为 170170。

第四秒,从 (1,2)(1,2) 走到 (2,2)(2,2),计数器的值为 180180。

第五秒,从 (2,2)(2,2) 走到 (3,2)(3,2),计数器的值为 180180。

第六秒,从 (3,2)(3,2) 走到 (3,3)(3,3),计数器的值为 180180,是 99 的倍数,逃出迷宫。
cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct State {
    int x, y, rem;
};

int main() {
    int n, m, p;
    cin >> n >> m >> p;

    vector<vector<int>> a(n, vector<int>(m));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> a[i][j];
        }
    }
    
    // b矩阵在计算余数时是不需要的,但仍需读入以消耗输入
    vector<vector<int>> b(n, vector<int>(m));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> b[i][j];
        }
    }

    if (p == 1) { // p-1 = 0, 无法取模
        cout << -1 << endl;
        return 0;
    }
    int mod = p - 1;

    vector<vector<vector<int>>> dist(n, vector<vector<int>>(m, vector<int>(mod, -1)));
    queue<State> q;

    int start_rem = a[0][0] % mod;
    dist[0][0][start_rem] = 0;
    q.push({0, 0, start_rem});

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

    while (!q.empty()) {
        State curr = q.front();
        q.pop();

        int t = dist[curr.x][curr.y][curr.rem];

        for (int i = 0; i < 4; ++i) {
            int nx = curr.x + dx[i];
            int ny = curr.y + dy[i];

            if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                int next_rem = (curr.rem + a[nx][ny]) % mod;
                
                if (dist[nx][ny][next_rem] == -1) {
                    dist[nx][ny][next_rem] = t + 1;
                    q.push({nx, ny, next_rem});
                }
            }
        }
    }

    cout << dist[n - 1][m - 1][0] << endl;

    return 0;
}
相关推荐
Smilecoc4 分钟前
方向导数与梯度
算法
瑞码空间13 分钟前
01背包:动态规划的Hello World
c++·算法·0/1背包问题
鱼子星_34 分钟前
【C++】反向迭代器:反向迭代器的底层认识与模拟实现
开发语言·c++·笔记·stl
Wang's Blog37 分钟前
AI Agent白手起家63: LangGraph 人机交互——让人类介入 AI 工作流
人工智能·算法·人机交互
郝学胜-神的一滴40 分钟前
[简化版 GAMES 104] 现代游戏引擎 05:游戏引擎世界构建核心机制深度解析
c++·程序人生·unity·游戏引擎·计算机图形学·opengl
Darkwanderor1 小时前
C++的流简介和简单使用
开发语言·c++
乐观勇敢坚强的老彭1 小时前
C++ STL 常用容器的速查表
java·c++·算法
北冥you鱼1 小时前
深入解析 Go 中 sync.YAML.Unmarshal:如何将 YAML 数据填充到 Config 结构体
开发语言·算法·golang
lingran__1 小时前
C++ STL map 与 set 底层剖析与模拟实现万字详解|基于红黑树,复刻 SGI-STL 泛型复用架构
开发语言·c++·stl·set·map·泛型编程·sgi-stl
段一凡-华北理工大学2 小时前
AI推动工业智能化转型~系列文章19:工艺参数寻优:离线优化与在线调优的算法谱系
开发语言·人工智能·算法·大模型应用·工艺参数优化·在线调优