51 Nod 1281 山峰和旗子

解题思路:首先先把能当做山峰的点找出来即a[i-1]<a[i]<a[i+1],收入集合中,其次从1开始遍历用二分找到距离大于等于i的,找到i面继续循环,往下循环直至找不到i面
注意:我们不仅要存放旗子的高度且要存储每面旗子初始的距离,所以要用结构体struct E,其次是在二分时循环变量的处理,当找第一个时,去处理第二个由于间距必须>=j,那么 e[2]-e[1]>=j <=> e[2]>=e[1]+j
即用二分找到大于等于e[1]+j的数,以此类推。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=50010; 4 int a[N],e[N]; 5 int main() { 6 int n; 7 cin>>n; 8 for(int i=1;i<=n;i++) 9 cin>>a[i]; 10 int k=0; 11 for(int i=2;i<n;i++) 12 { 13 if(a[i]>a[i-1]&&a[i]>a[i+1]) 14 { 15 e[k]=i; 16 k++; 17 i++; 18 } 19 } 20 if(k==0) 21 { 22 cout<<0; 23 return 0; 24 } 25 if(k==1) 26 { 27 cout<<1<<endl; 28 return 0; 29 } 30 for(int j=1;j<=k;j++) 31 { 32 int ans=0; 33 for(int i=0;i<k;) 34 { 35 ans++; 36 int t=lower_bound(e,e+k,e[i]+j)-e; 37 if(t==k) break; 38 else { 39 i=t; 40 } 41 if(ans==j) break; 42 } 43 if(ans<j) 44 { 45 cout<<j-1; 46 break; 47 } 48 } 49 return 0; 50 }