题解:P15503 [ICPC 2025 APC] Boarding Queue
题目思路
读题发现 \(r,c\le1000\),直接模拟即可,不会超时。
还发现,过了 \(t\) 时间后,第 \(i\) 个人就在一开始第 \(i-t\) 个人的位置,因此可以开一个 pair 数组记录每个人一开始的位置。每次分别查看四个方向的人,查重并记录。
输出的分母题目已经给出为 \(n-1\),分子则是我们记录的人数。
还有一些要注意的点 (作者血泪的教训 QwQ) :
- 注意查重。
- 注意越界。
- 注意这个位置在 \(t\) 时间前有没有人,以及现在有没有人(当前这点为不为 \(0\))。
- 输出的分数不要约分!
注意到这几点后,就可以轻松做出这道题了。
AC 代码
时间复杂度为 \(O(rc)\)。
:::success[C++ 代码]{open}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int r, c, n, p, cnt;
int f[N][N];
int v[N * N];
pair<int, int> w[N * N];
void solution() {
cin >> r >> c >> n >> p;
// 输入网格并记录每个非零数字的位置
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> f[i][j];
if (f[i][j] != 0) {
w[f[i][j]] = {i, j};
}
}
}
// 从p开始向前遍历
for (int i = p; i >= 1; i--) {
int t = p - i;
int x = w[i].first, y = w[i].second;
// 检查四个方向
// 左边
if (y - 1 >= 1 && f[x][y - 1] && f[x][y - 1] + t <= n) {
if (!v[f[x][y - 1] + t]) {
cnt++;
v[f[x][y - 1] + t] = 1;
}
}
// 右边
if (y + 1 <= c && f[x][y + 1] && f[x][y + 1] + t <= n) {
if (!v[f[x][y + 1] + t]) {
cnt++;
v[f[x][y + 1] + t] = 1;
}
}
// 上面
if (x - 1 >= 1 && f[x - 1][y] && f[x - 1][y] + t <= n) {
if (!v[f[x - 1][y] + t]) {
cnt++;
v[f[x - 1][y] + t] = 1;
}
}
// 下面
if (x + 1 <= r && f[x + 1][y] && f[x + 1][y] + t <= n) {
if (!v[f[x + 1][y] + t]) {
cnt++;
v[f[x + 1][y] + t] = 1;
}
}
}
cout << cnt << "/" << n - 1;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) solution();
return 0;
}
:::

浙公网安备 33010602011771号