【AT2165】Median Pyramid Hard

题目

题目链接:https://www.luogu.com.cn/problem/AT2165
给出一个 (n) 层的方格金字塔,自顶向下依次标号为第 (1) 到第 (n) 层。
其中第 (i(1 le i le n)) 层有 (2i − 1) 个方格。(具体形态见下面的图)
(n) 层有一个 (1)(2n-1) 的排列,其他层的数字按以下规则生成:方格 b 中填写的整数,是方格 b 正下方,左下方和右下方方格中所写整数的中位数。
现在给出第 (n) 层的数字,请你求第一层的数字。

思路

注意下文的 (n) 等于原题中 (2n-1)
可以二分答案,然后套路性装换为 (01) 序列。
假设转换为 (01) 序列之后,离中间最近的相邻两个数字相同的是位置 (i)。不妨设 (frac{n}{2} leq i)(a[i]=a[i+1]=1)
那么显然上一行的位置 (i)(i+1) 均是 (1),而且位置 (i-1) 也应该是 (1),否则必然有 (a[i-1]=a[i-2]=0),那么就不满足 (a[i])(a[i+1]) 是最接近中间点的。
所以第一行的值就是距离 (frac{n}{2}) 最近的相邻数字相等的数值。因为有奇数列且每一个位置均为 (01),所以不会出现距离相等的情况。
但是有一种特殊情况,就是相邻数字均不相等,那么第一行数值就是最后一行第一个位置的数值。
如果第一行为 (1) 说明答案不小于 (mid),否则答案小于 (mid)

代码

#include <bits/stdc++.h>
using namespace std;

const int N=200010;
int n,l,r,mid,a[N];

bool check(int k)
{
	int m=n/2+1;
	for (int i=0;i<n/2;i++)
	{
		if (a[m+i]<k && a[m+i+1]<k) return 0;
		if (a[m-i]<k && a[m-i-1]<k) return 0;
		if (a[m+i]>=k && a[m+i+1]>=k) return 1;
		if (a[m-i]>=k && a[m-i-1]>=k) return 1;
	}
	return a[1]>=k;
}

int main()
{
	scanf("%d",&n);
	n=n*2-1;
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	l=1; r=n;
	while (l<=r)
	{
		mid=(l+r)>>1;
		if (check(mid)) l=mid+1;
			else r=mid-1;
	}
	printf("%d",l-1);
	return 0;
}
原文地址:https://www.cnblogs.com/stoorz/p/13904469.html