To_Heart—题解——AT2165

这是一篇解题报告

首先,看到标签,考虑二分答案。

我们二分答案(即塔顶的值),把大于或等于这个值的变为1,否则变为0。

很容易发现,如果塔顶的答案是1,那么就说明值可以更大,否则相反。

复制一波样例

   4
  454
 36454
1637452

因为答案是4,所以我们把3、4、5为答案的情况都拿出来观察一下


3:
   0
  000
 10000
1010001

5:
   1
  111
 10111
1010111

4:
   1
  101
 10101
1010101

很容易想到从左往右一直找,直到找到两个相同的值,并返回这个值。如果没有,那么就看第n项是0还是1,是0则可以,是1则不行

可是会被下面这种情况hack


   1
  011
 00110
0001100		

那么会不会是中间往两边的找到的第一组相等的值呢?

发现没有问题,but



   0
  010
 01010
0101010

    0
   010
  01010
 0101010
010101010

可以发现在找不到相同的相邻项时,层数不同,第n项的答案的影响不同。

然后可以发现如果是奇数层,那么塔顶的值就和塔底的第n项相同,否则就不同

然后就做完了qwq

代码如下(注释显示艰辛历程)

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

int n;
int a[400005];
int b[400005];

bool Cheak(int  x){
    
    
	for(int i=1;i<=n*2-1;i++)
		b[i]=a[i]>=x;
	for(int i=1;i<n;i++){
    
    
		if(b[n-i]==b[n-i+1])
			return b[n-i+1];
		if(b[n+i]==b[n+i-1])
			return b[n+i-1];
	}
	if(n&1)
		return b[n];
	return !b[n];
}

int main(){
    
    
	cin>>n;
	for(int i=1;i<=n*2-1;i++)
		scanf("%d",&a[i]);
	int l=1,r=2*n-1;
	int ans=l;
	while(l<=r){
    
    
		int mid=(l+r)>>1;
		if(Cheak(mid))
			ans=mid,l=mid+1;
		else
			r=mid-1;
//		printf("%d %d\n",l,r);
	}
	printf("%d\n",ans);
	return 0;
}
/*
   4
  454
 36454
1637452

3:
   0
  000
 10000
1010001

5:
   1
  111
 10111
1010111

4:
   1
  101
 10101
1010101

   1
  011
 00110
0001100			qwq hack了 

中间往边?
   0
  100
 11001
1110011 

中间贡献最大 

如果没有相同?
   1
  101
 10101
1010101

   0
  010
 01010
0101010
 
看中间是否为1。 

不对qwq 

    0
   010
  01010
 0101010
010101010

层数变化会改变ans
F**k 
*/

猜你喜欢

转载自blog.csdn.net/xf2056188203/article/details/115905402