1281 山峰和旗子
用一个长度为N的整数数组A,描述山峰和山谷的高度。山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]。
现在要在山峰上插上K个旗子,并且每个旗子之间的距离 >= K,问最多能插上多少个旗子(即求K的最大值)。两个山峰之间的距离为|P - Q|。
以上图为例,高度为:1 5 3 4 3 4 1 2 3 4 6 2。其中可以作为山峰的点为:1 3 5 10。
放2面旗子, 可以放在1 和 5。
放3面旗子, 可以放在1 5 和 10。
放4面旗子, 可以放在1 5 和 10,之后就放不下了。
所以最多可以放3面旗子。
Input
第1行:一个数N,表示数组的长度(1 <= N <= 50000)。 第2 - N + 1行:每行1个数Ai(1 <= Ai <= 10^9)。
Output
输出最多能插上多少面旗子(即求K的最大值)。
Input示例
12 1 5 3 4 3 4 1 2 3 4 6 2
Output示例
3
思路:2分,找到可以插旗子的点,然后二分旗子个数,看是否满足有这么多个
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[50004]; 5 int b[50004]; 6 int s=0; 7 8 int slove(int x){ 9 int sum=0,ssum=0; 10 for(int i=2;i<=s;i++){ 11 sum+=b[i]-b[i-1]; 12 // cout<<i<<" "<<sum<<endl; 13 if(sum>=x){ 14 ssum++;sum=0; 15 } 16 } 17 // cout<<endl; 18 return ssum+1; 19 } 20 int main(){ 21 int n; 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++){ 24 scanf("%d",&a[i]); 25 } 26 27 for(int i=2;i<n;i++){ 28 if(a[i]>a[i-1]&&a[i]>a[i+1]){ 29 b[++s]=i; 30 } 31 } 32 int l=1,r=s,mid; 33 int ans=0; 34 while(l<=r){ 35 int mid=(l+r)>>1; 36 //cout<<mid<<" "<<slove(mid)<<endl; 37 if(slove(mid)>=mid){ 38 ans=mid; 39 l=mid+1; 40 } 41 else r=mid-1; 42 } 43 cout<<ans<<endl; 44 }