51Nod_1285 山峰和分段
http://www.51nod.com/Challenge/Problem.html#!#problemId=1285
题目
用一个长度为N的整数数组A,描述山峰和山谷的高度。山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]。
以上图为例,高度为:1 5 3 4 3 4 1 2 3 4 6 2。
现在要将整个山分为K段,要求每段的点数都一样,且每段中都至少存在一个山峰,问最多可以分为多少段。
输入
第1行:一个数N,表示数组的长度(1 <= N <= 50000)。第2 - N + 1行:每行1个数Ai(1 <= Ai <= 10^9)。
输出
输出最多可以将山分为多少段。
样例输入
12
1
5
3
4
3
4
1
2
3
4
6
2
样例输出
3
分析
统计山峰的个数,并求前缀和,最后进行枚举即可。
C++程序
#include<iostream>
#include<cstring>
using namespace std;
const int N=50005;
int a[N];
bool vis[N];
int pre[N];
int main()
{
int n;
while(cin>>n)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
cin>>a[i];
int k=0,i,j;
//统计山峰信息
for(i=2;i<n;i++)
if(a[i]>a[i-1]&&a[i]>a[i+1])
{
vis[i]=1;
k++;
}
//前缀和
pre[0]=0;
for(int i=1;i<=n;i++)
{
pre[i]=pre[i-1];
if(vis[i]) pre[i]++;
}
//枚举
for(i=k;i>=1;i--)
{
if(n%i) continue;
int len=n/i;
for(j=len;j<=n;j+=len)
if(pre[j]-pre[j-len]==0)
break;
if(j>n)
break;
}
cout<<i<<endl;
}
return 0;
}