题目:Median Pyramid Hard
思路:
二分金字塔顶的数字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 200000int 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;
}