中位数只关心数的大小关系,而不是确切的值,所以我们可以从 1 ~ (2 * n - 1) 二分答案出一个数 X,将底端 < X 的数赋为 0,> X 的数赋为 1。
一个格子的值一定等于 这个格子下面三个格子的数中至少有两个数相同的数。
第 n 列的最顶部格子的值一定和离这个格子最近的两个有相同数的格子的值相同。
那么判断 mid 是否可行,我们只要从最低端第 n 列开始 同时向左向右不停查找 有相同的值的两个相邻格子,一旦找到有这样的两个格子就返回这两个格子的值。注意如果没有这样的两个格子,显然就返回第一个数值即可。
如果返回值为 1 则表示这个二分出来的值大于了最后答案,如果为 0 反之,显然我们就是要求最小的返回值为 1 的 mid。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int nn, n;
int a[N << 1];
int small(int x, int y, int k) {
return (a[x] <= k && a[y] <= k);
}
int big(int x, int y, int k) {
return (a[x] > k && a[y] > k);
}
bool check(int k) {
if (small(n, n - 1, k) || small(n, n + 1, k)) return 0;
if (big(n, n - 1, k) || big(n, n + 1, k)) return 1;
for (int i = 1; i < n - 1; i ++) {
if (small(n - i, n - i - 1, k) || small(n + i, n + i + 1, k)) return 0;
if (big(n - i, n - i - 1, k) || big(n + i, n + i + 1, k)) return 1;
}
return big(1, 1, k);
}
int main() {
scanf("%d", &n);
nn = 2 * n - 1;
for (int i = 1; i <= nn; i ++) scanf("%d", &a[i]);
int l = 1, r = nn, pos;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) l = mid + 1;
else r = mid;
}
printf("%dn", r);
return 0;
}
最后
以上就是玩命寒风最近收集整理的关于【AGC006 D - Median Pyramid Hard】【思维题】的全部内容,更多相关【AGC006内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复