2012J_2:寻宝

洛谷:P1076
OJ: P4934

算法分析:

这是一道纯模拟题,主要就是把数据读入,然后依靠下一层的楼梯给的关系,找到上一层的位置。一层一层地模拟。

每层的位置。根据题面中的:从j号房间的楼梯爬到上一层到达的房间一定也是j号房间可知,我们只需要用一个变量来储存自己的位置就行了。

但是!

题目中有十分明显的提示:对于100%数据,有0<N≤10000 , 0<M≤100 , 0<x≤1,000,000。这个x,单纯的模拟是不行的,需要考虑一下周期性问题,在每层模拟时用要找的数模一下当层的楼梯数,就可以解决问题了!

代码实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**************************************************************** 
 * Description: 2012年NOIP普级组  寻宝
 * Author: Alex Li
 * Date: 2024-10-10 11:00:02
 * LastEditTime: 2024-10-10 11:03:58
****************************************************************/
#include <iostream>
using namespace std;

int floorCount, roomCount;            // 楼层数(不包括顶层)和每层的房间数
int hasStair[10010][110];             // hasStair[i][j] 表示第 i 层第 j 号房间是否有楼梯(1 有,0 无)
int signNumber[10010][110];           // signNumber[i][j] 表示第 i 层第 j 号房间指示牌上的数字
int stairRoomCount[10010];            // stairRoomCount[i] 表示第 i 层有楼梯的房间总数
int key = 0;                          // 打开宝箱的密钥
int currentRoom;                      // 当前所在的房间编号

int main() {
    cin >> floorCount >> roomCount;

    // 读取每层每个房间的信息
    for (int i = 1; i <= floorCount; i++) {
        stairRoomCount[i] = 0; // 初始化有楼梯的房间数为 0
        for (int j = 1; j <= roomCount; j++) {
            cin >> hasStair[i][j] >> signNumber[i][j];
            if (hasStair[i][j])
                stairRoomCount[i]++; // 统计每层有楼梯的房间数
        }
    }

    cin >> currentRoom;
    currentRoom += 1; // 调整房间编号,从 1 开始

    // 模拟寻宝过程
    for (int i = 1; i <= floorCount; i++) {
        // 累加指示牌上的数字到密钥中
        key += signNumber[i][currentRoom];
        key %= 20123; // 取模防止溢出

        // 计算需要找到的第 x 个有楼梯的房间
        int x = signNumber[i][currentRoom] % stairRoomCount[i];
        if (x == 0) x = stairRoomCount[i]; // 如果余数为 0,则取最大值

        currentRoom--; // 准备逆时针查找,先减一

        // 逆时针查找第 x 个有楼梯的房间
        while (x) {
            currentRoom++; // 向前移动房间编号
            if (currentRoom > roomCount)
                currentRoom = 1; // 超过房间总数,循环回第一个房间
            if (hasStair[i][currentRoom])
                x--; // 找到有楼梯的房间,计数减一
        }
        // 上楼后,房间编号保持不变
    }

    cout << key % 20123; // 输出密钥的最终结果
    return 0;
}
Scroll to Top