Problem
用一个长度为N的整数数组A,描述山峰和山谷的高度。山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]。
现在要将整个山分为K段,要求每段的点数都一样,且每段中都至少存在一个山峰,问最多可以分为多少段。
Solution
枚举因数,前缀和优化查询。
复杂度是因子之和,试了一下,1e6之内一个大于5*n的也没有,最大比率4.5多一点。
Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | #include<stdio.h>#include<set>
 #include<iostream>
 #include<algorithm>
 #include<cstring>
 #define mem(ss) memset(ss,0,sizeof(ss))
 #define rep(d, s, t) for(int d=s;d<=t;d++)
 #define rev(d, s, t) for(int d=s;d>=t;d--)
 typedef long long ll;
 typedef long double ld;
 typedef double db;
 #define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
 using namespace std;
 int n;
 int a[50020];
 int sum[50020];
 int main() {
 io_opt;
 cin>>n;
 for(int i=1;i<=n;i++){
 cin>>a[i];
 }
 for(int i=2;i<=n-1;i++){
 if(a[i]>a[i-1]&&a[i]>a[i+1]){
 sum[i]=1;
 }
 sum[i]+=sum[i-1];
 }
 sum[n]=sum[n-1];
 for(int i=n;i>=1;i--){
 if(n%i==0){
 bool fg=true;
 int l=n/i;
 for(int j=1;j<=i;j++){
 if(sum[j*l]-sum[(j-1)*l]<1){
 fg=false;
 break;
 }
 }
 if(fg){
 cout<<i<<endl;
 return 0;
 }
 }
 }
 cout<<"0"<<endl;
 return 0;
 }
 
 |