题目1 : 循环数组
时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB
描述
给定包含N个整数的数组A1, A2, ... AN,你可以选择任意一个Ai,将Ai旋转到数组第一项,即将数组变成:
Ai, Ai+1, Ai+2, ... AN, A1, A2, ..., Ai-1
现在小Hi希望旋转之后的数组满足:
对于任意K(1 ≤ i ≤ N),前K项的和都是正数。
例如对于A=[3, -5, 2, -2, 3, 0],旋转成[3, 0, 3, -5, 2, -2]满足条件。
请你输出i,代表将Ai旋转到第一项满足条件。
如果有多解,你可以输出任意一个i。如果无解输出-1。
输入
第一行包含一个整数N。
第二行包含N个整数A1, A2, ... AN。
对于50%的数据,1 ≤ N ≤ 1000
对于100%的数据,1 ≤ N ≤ 100000, -1000000 ≤ Ai ≤ 1000000
输出
一个整数表示答案。
6 3 -5 2 -2 3 0样例输出
5
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <queue>
using namespace std;
const int maxn = 1e5+1000;
const int inf = 0x3f3f3f3f;
const long long INF = (long long)(inf*inf);
long long a[maxn];
vector<int> mark;
long long pre_sum[maxn],hou_sum[maxn];
void init()
{
mark.clear();
memset(pre_sum,0,sizeof(pre_sum));
memset(hou_sum,0,sizeof(hou_sum));
}
int main(void)
{
int n;
scanf("%d",&n);
init();
long long sum=0;
for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
sum+=a[i];
pre_sum[i]=pre_sum[i-1]+a[i];
}
if(sum<=0)
{
puts("-1");
}
else
{
for(int i=n; i>=1; i--)
{
hou_sum[i]=hou_sum[i+1]+a[i];
if(hou_sum[i]>0) mark.push_back(i);
}
int len = mark.size();
int ans;
long long Max=-INF;
for(int i=0; i<len; i++)
{
if((pre_sum[mark[i]-1]+hou_sum[mark[i]])>0)
{
long long temp = hou_sum[mark[i]];
if(temp > Max)
{
Max = temp;
ans = mark[i];
}
}
}
printf("%d\n",ans);
}
return 0;
}