思路:
二分金字塔顶的数字mid,将大于等于mid的数看做1,小于mid的数看做0。
对于此时的01序列,假设有两相邻数字相同,那么塔顶的数等于离中心最近的相邻数字对的数。
如果没有两数相邻,塔顶的数等于最左边的数(最右边的数也可以)。
数据生成器:
#include<bits/stdc++.h>
using namespace std;
#define maxn 4
#define maxk 4
#define Rand() (rand()+rand()%19260817)
int n,r,k;
int main() {
srand(time(NULL));
n=Rand()%maxn+1;
printf("%d\n",n);
for(int i=1;i<=n*2-1;i++) printf("%d ",Rand()%maxk+1);
return 0;
}
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
#define maxm 200000
int n,m;
int a[maxm+5];
int c[maxm+5];
void readin(){
scanf("%d",&n);
m=n*2-1;
for(int i=1;i<=m;i++) {
scanf("%d",&a[i]);
}
}
void Turn(int x) {
for(int i=1;i<=m;i++){
c[i]=(a[i]>=x);
}
}
bool judge(int x){
Turn(x);
int p1=0,p2=m+1;
for(int i=n;i>=2;i--){
if(c[i]==c[i-1]){
p1=i;
break;
}
}
for(int i=n;i<m;i++) {
if(c[i]==c[i+1]) {
p2=i;
break;
}
}
if(p1==0&&p2==m+1) return c[1];
if(n-p1>p2-n) return c[p2];
else return c[p1];
}
int binsearch() {
int l=0,r=m;
while(l+1<r) {
int mid=l+(r-l)/2;
if(judge(mid)) l=mid;
else r=mid;
}
if(judge(l+1)) return l+1;
if(!judge(l)) return l-1;
else return l;
}
int main(){
readin();
int ans=binsearch();
printf("%d",ans);
return 0;
}