首页 > 其他 > 详细

agc006_d

时间:2020-08-31 21:27:40      阅读:76      评论:0      收藏:0      [点我收藏+]

题目链接

点击打开

题解

二分答案,将每一个数转化为 \(0,1\) 。可以据此判断最顶上的数是否 \(\ge x\)

那么可以发现,如果最后一行存在 00 和 11 这种东西,那么一定能延续到上方。

否则没有相邻相同的,那么直接做即可。

代码

#include <cstdio>
using namespace std;
const int NN = 1e5 + 5, N2N = NN * 2 - 1;
int N, A[N2N], B[N2N];
bool check(int m) {
	for (int i = 1; i <= 2 * N - 1; ++i) B[i] = (A[i] >= m);
	bool type = 0;
	for (int i = 1; i < 2 * N - 1; ++i)
		if (B[i] == B[i + 1]) {
			type = 1;
			break ;
		}
	if (!type) {
		if ((N - 1) % 2 == 0)
			return B[N];
		else return B[N] ^ 1;
	} else {
		int p1 = 2 * N; //有可能右边没有,所以得有个初始值
		for (int i = N; i < 2 * N - 1; ++i)
			if (B[i] == B[i + 1]) {
				p1 = i;
				break ;
			}
		int p2 = 0;
		for (int i = 1; i < N; ++i)
			if (B[i] == B[i + 1]) {
				p2 = i + 1;
//				break ; //这里不能 break...要找到最靠右的
			}
		return B[((p1 - N) > (N - p2)) ? p2 : p1];
	}
}
int main() {
	freopen("median.in", "r", stdin);
	freopen("median.out", "w", stdout);
	scanf("%d", &N);
	for (int i = 1; i <= 2 * N - 1; ++i)
		scanf("%d", &A[i]);
	int L = 1, R = 2 * N - 1, ans = 0;
	while (L <= R) {
		int m = (L + R) >> 1;
		if (check(m)) {
			ans = m;
			L = m + 1;
		} else R = m - 1;
	}
	printf("%d\n", ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

agc006_d

原文:https://www.cnblogs.com/YouthRhythms/p/13591720.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!