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;
}
相关推荐
田梓燊13 小时前
力扣:23.合并 K 个升序链表
算法·leetcode·链表
re林檎13 小时前
算法札记——4.27
算法
数据牧羊人的成长笔记14 小时前
逻辑回归与Softmax回归
算法·回归·逻辑回归
郑州光合科技余经理14 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
张健115640964816 小时前
使用信号量限制并发数量
开发语言·c++
jc062016 小时前
6.1云原生之Docker
c++·docker·云原生
d111111111d17 小时前
STM32-UART封装问题解析
笔记·stm32·单片机·嵌入式硬件·学习·算法
叶子野格18 小时前
《C语言学习:指针》12
c语言·开发语言·c++·学习·visual studio
Jiangxl~19 小时前
IP数据云如何为不同行业提供精准IP查询与风险防控解决方案?
网络·网络协议·tcp/ip·算法·ai·ip·安全架构
Fuyo_111919 小时前
C++ 内存管理
c++·笔记