P4771 八百标兵奔北坡 题解
_Spectator_ · · 题解
可能更好的食用体验
upd on 2024.10.16:润色码风,修改了因专栏更新而炸掉的
\LaTeX 。
本题解写得比较细,作者的初衷是想给更多刚入门的新手 OIer 看,大佬们可根据自身需求忽略部分内容。
{\color{#00CD00}\text{题意简述}}
估计很多人都不太清晰题意,尤其是“北边”的含义。首先,“北边”指的是一个
以及“切比雪夫距离”,题目描述写的也不太清楚。它指的是一个点
还有“山”的定义,只要一个点的高度比它东、南、西、北四个点的高度都要高(高度相等的不算),该点即为山。
弄明白这几点,这道题也就更容易着手了。
{\color{#00CD00}\text{主要思路}}
很多大佬这道题都是用 DP 做的,但这道题作为一道橙题,其实就是一道简单的枚举题。问题在于如何枚举。
假设在
首先是行的枚举范围。通过上面的图示不难看出,行的范围即为
其次是列的枚举范围。可以发现,列的范围其实是与当前的行数有关的。有了前面枚举的差
这样枚举下来,就能把每只 Pool Babingbaboom!。
弄明白了如何枚举,其余细节请读者阅读代码,自行理解。
{\color{#00CD00}\text{完整代码}}
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i=a; i<=b; i++)
#define ismountain(i, j)\
a[i][j]>a[i-1][j] && a[i][j]>a[i+1][j] && a[i][j]>a[i][j-1] && a[i][j]>a[i][j+1]
using namespace std;
const int N = 1e3 + 5;
int n, m, k, x, y;
int a[N][N], h[N][N];
int bbbb(int x, int y){
rep(i, 0, x-1) rep(j, max(0, y-i), min(m, y+i)) //枚举每个 Babingbaboom 可以到达的位置
if(h[x-i][j]) return i; //找到一座山,i 即为答案
return -1; //-1 表示在此范围内没有山
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m >> k;
rep(i, 1, n) rep(j, 1, m) cin >> a[i][j];
rep(i, 1, n) rep(j, 1, m) h[i][j] = ismountain(i,j); // 预处理
rep(i, 1, k){
cin >> x >> y;
int ans = bbbb(x, y);
if(ans != -1) cout << ans << "\n";
else cout << "Pool Babingbaboom!\n";
}
return 0;
}