CSP历年复赛题-P1076 [NOIP2012 普及组] 寻宝
原题链接:https://www.luogu.com.cn/problem/P1076
题意解读:n+1层楼,每层楼m个房间,编号0~m-1成环状,每个房间有一个指示牌数字(表示逆时针遇到第几个有楼梯的房间后上楼),有的有向上的楼梯,给定一个底层的起始房间,计算到首次到每一层(1~n层)的房间指示牌数字之和。
解题思路:
每层楼一个环形数组代表房间,因此用二维数组即可表示,为便于处理,数组下标都从0开始。
此题关键在于上到每一层,要根据指示牌数字找到第x个有楼梯的房间,如果直接枚举,x最大为10^6,楼层为10^5,将超时!
又因为每层楼房间不超过100,因此可以将每层楼有楼梯的房间数提前统计出来,用x % 当前楼层有楼梯的房间数,对余数再进行枚举,就能大大缩减枚举时间。
这里要注意的点是,如果x % 房间数s[i] = 0,则要找到第s[i]个有楼梯的房间,不能是第0个。
最后,注意结果要对20123取模。
100分代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 10005, M = 105, MOD = 20123;
int n, m, start;
int v[N][M]; //v[i][j]表示i层,j号房间是否有通往上层的楼梯
int w[N][M]; //w[i][j]表示i层,j号房间指示牌的数字
int s[N]; //s[i]表示第i层一共有多少个楼梯
int ans;
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cin >> v[i][j] >> w[i][j];
s[i] += v[i][j];
}
}
cin >> start;
ans += w[0][start];
for(int i = 0; i < n - 1; i++) //寻找每一层上楼的房间,第n层不用找
{
int x = w[i][start]; //当前楼层起始房间的指示牌数字
int r = x % s[i]; //找第r个有楼梯的房间即可,缩短查找时间
if(r == 0) r = s[i]; //关键句,如果正好s[i]倍,要找第s[i]个,不能是0个
int cnt = 0;
while(true)
{
if(v[i][start] == 1)
{
if(++cnt == r) break;
}
start = (start + 1) % m;
}
ans += w[i+1][start];
ans %= MOD;
}
cout << ans;
return 0;
}
分类:
CSP-J复赛真题解析
标签:
模拟法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?