算法
(枚举,模拟) $O(nm)$
模拟从第 $1$ 层走到第 $n + 1$ 层的整个过程,每次找出从当前房间开始第 $x$ 个有梯子的房间即可。注意,这里如果直接模拟,那么最坏情况下每层都需要枚举 $10^6$ 次,总计算量会达到 $10^{10}$ ,会超时。这里可以先求出当前这层中总共有多少个梯子,然后将 $x$ 对梯子总数取模之后再枚举,这样可以将每层的计算量降到 $10^2$,就不会超时了。
最终每层遇到的 $x$ 之和就是答案,不要忘记将答案对 $20123$ 取模。
时间复杂度
一共模拟 $n$ 层,每层的计算量和每一层的房间数量成正比,因此总时间复杂度是 $O(nm)$,其中 $m$ 是每一层的房间数量。
C++ 代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010, M = 110, mod = 20123;
int n, m, k;
bool st[N][M];
int x[N][M];
int main()
{
scanf("%d%d", &n, &m);
int res = 0;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
scanf("%d%d", &st[i][j], &x[i][j]);
scanf("%d", &k);
for (int i = 0; i < n; i ++ )
{
int s = 0;
for (int j = 0; j < m; j ++ ) s += st[i][j];
int t = x[i][k];
res = (res + t) % mod;
t %= s;
if (!t) t = s;
for (int j = k; ;j = (j + 1) % m)
{
if (st[i][j])
{
if (-- t == 0)
{
k = j;
break;
}
}
}
}
printf("%d\n", res);
return 0;
}
%%yxc啊啊啊
[ohh]
y总,为什么可以取模后再计算???谢谢
为了降低时间复杂度
因为原问题的过程可以看作是一个周期函数,所以可以取模
%%yxc
谢谢hh