• 洛谷P1076 寻宝 题解 模拟


    题目链接:https://www.luogu.com.cn/problem/P1076

    解题思路:
    这道题目是一道标准的模拟题。一开始我们在第 (1) 层的 (p) 号房间,然后我们要沿着逆时针方向找 (x) 把钥匙,然后进入上一层。

    我们可以暴力模拟一下这个算法,看看在最坏情况下的的时间复杂度。

    如下所述是我能够想到的最坏情况:

    (N = 10000) 层,每层楼有 (M = 100) 个房间,每一层我都要寻找 (x = 1,000,000) 把钥匙,每一层只有一把钥匙。

    这种情况下,我要转 (10^6) 圈才能收集 (x) 把钥匙,每一圈我遍历了 (M=100) 个房间,再算上层数 (N=10^4),总的时间复杂度达到了

    [10^6 imes 10^2 imes 10^4 = 10^{12} ]

    是会超时的。

    优化:

    我可以开一个 (sum[]) 数组,其中 (sum[i]) 用于记录第 (i) 层的房间总共有多少把钥匙。

    然后,我假设我刚进入第 (i) 层的时候在第 (p) 号房间,嫔妾房间上写的号码是 (x),那么:

    • 如果 (x) 不能被 (sum[i]) 整除,则我们只需要从 (p) 开始逆时针找到第 (x ext{ mod } sum[i]) 把钥匙就可以了(这里 ( ext{mod}) 表示取余数);
    • 否则((x) 能被 (sum[i]) 整除),则我们只需要从 (p) 的前一个房间按照顺时针顺序找到第一把有钥匙的房间就可以了。

    比如,我当前在第 (i) 层的第 (p) 个房间,上面写着数字 (8) —— 也就是说我要找到第 (8) 把钥匙对应的房间,同时 (sum[i]=3),所以我饶了一圈之后回到第 (p) 个房间,我还剩下 (8-3=5) 把钥匙;我饶了两圈之后回到第 (p) 个房间,我还剩下 (5-3=2) 把钥匙。所以这跟我一开始就找 (8 ext{ mod } 3 = 2) 把钥匙是一样的效果。

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int has[10010][110], num[10010][110], sum[10010], n, m, p, ans;
    const int MOD = 20123;
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                cin >> has[i][j] >> num[i][j];
                sum[i] += has[i][j];
            }
        }
        cin >> p;
        for (int i = 0; i < n; i ++) {
            int val = num[i][p] % sum[i];
            ans = (ans + num[i][p]) % MOD;
            if (val) { // 如果不能整除,从p开始逆时针找第 val%sum[i]把钥匙
                while (true) {
                    if (has[i][p]) {
                        val --;
                        if (!val) break;
                        p = (p+1) % m;
                    }
                    else {
                        p = (p+1) % m;
                    }
                }
            }
            else {  // 如果能整除,从p-1开始顺时针找第一把钥匙
                while (true) {
                    p = (p+m-1) % m;
                    if (has[i][p]) break;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    Windows上安装PyV8
    Windows鼠标右键菜单添加SublimeText打开选项
    Windows使用Python虚拟环境
    Windows同时安装Python2和Python3
    Windows使用Cmder
    Visual Studio Code配置
    Windows 10使用Tesseract-OCR出现WindowsError: [Error 2]
    用pymysql代替MySQLdb
    使用python来搞定redis的订阅功能
    来写一个最基本的装饰器吧!
  • 原文地址:https://www.cnblogs.com/quanjun/p/12698163.html
Copyright © 2020-2023  润新知