zoukankan      html  css  js  c++  java
  • [AGC06D] Median Pyramid Hard (玄学)

    Description

    现在有一个N层的方块金字塔,从最顶层到最底层分别标号为1...N。

    第i层恰好有2i−1个方块,且每一层的中心都是对齐的。

    这里写图片描述

    这是一个N=4的方块金字塔

    现在,我们首先在最底层填入一个2N−1的排列。之后,我们从i−1层开始,逐步向上填入每一层的数。

    对于第i((1≤ i <N))层中位置为x的方块,它的值为左下方、正下方和右下方的三个数的中位数。形式化地描述,就是(i+1)层中(x-1)(x)(x+1)三个位置的中位数。

    给定一个N和长度为2N−1的排列,请还原出最顶层唯一一个方块中的数值。

    下图就是一个还原的例子:

    这里写图片描述

    Input

    第一行一个正整数N(2≤N≤105)

    接下来一行有2N−1个正整数a1,a2,...,a2N−1,表示最底层的填数情况。保证a是个排列。

    Output

    只有一个正整数,表示最顶层那唯一一个格子里的数。

    题解:

    我还是太蒟了,没有想到能二分答案……

    我们二分塔顶的值,把小于等于这个值的变为1,大于变为0。

    我们可以发现如果有多个个1或0连在一起,那么他们就无法被分开,他会一直往上走。

    那也就是说,最后那组先走到顶那组就赢了,那就要看那组离中心更近。

    那会不会存在两个不同阵营的组距离一样远能,你会发现这是不可能的。

    因为,如果距离相等,那么中间一定是奇数个位置,我们用1和0,交替隔开两组,那么最后一个位置肯定会和左边或者右边一样,又形成一个组,所这两个组要么都是1,要么都是0。

    解决了这些问题就能愉快的判断了!

    CODE:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int n,a[200005];
    
    inline bool check(const int &k){
    	if((a[n-1]<=k&&a[n]<=k)||(a[n]<=k&&a[n+1]<=k))return 1;
    	if((a[n-1]> k&&a[n]> k)||(a[n]> k&&a[n+1]> k))return 0;
    	for(int i=1;i<n-1;i++){
    		if((a[n+i]<=k&&a[n+i+1]<=k)||(a[n-i]<=k&&a[n-i-1]<=k))return 1;
    		if((a[n+i]> k&&a[n+i+1]> k)||(a[n-i]> k&&a[n-i-1]> k))return 0;
    	}
    	return a[1]<=k;
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<n<<1;i++)scanf("%d",a+i);
    	int l=1,r=(n<<1)-1;
    	while(l<r){
    		int mid=l+r>>1;
    		if(check(mid))r=mid;
    		else l=mid+1;
    	}
    	printf("%d",l);
    }
    

    挺短的把……

  • 相关阅读:
    数组练习1
    学习进度04
    求一个数组的最大子数组之和02
    求一个数组的最大子数组之和01
    学习进度03
    四则运算的功能添加版02
    第二周学习进度
    Right-BICEP 测试四则运算程序
    实现四则运算的功能添加版01
    本周实验PSP0 过程文档
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9481104.html
Copyright © 2011-2022 走看看