zoukankan      html  css  js  c++  java
  • 【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;
    }
    
  • 相关阅读:
    驱动中回溯函数的调用关系
    CSI-MIPI学习笔记
    1920*1080分辨率和1080p,1080i的关系
    V4L2驱动内核文档翻译(一)
    signal()信号操作
    617. Merge Two Binary Trees
    Java中的集合
    Switch能否用string做参数
    Java面试题
    八种基本数据类型的大小,以及他们的封装类
  • 原文地址:https://www.cnblogs.com/stoorz/p/13904469.html
Copyright © 2011-2022 走看看