题意:
让你选取三个位置,使得数列分成四部分,每部分的和都相等,问你能否成功.(ai>=0&&ai<=1e9,)
思路:
这个题的话,由于前缀和都是递增的,所以的话我们可以开一个双指针,一个从前往后,一个从后往前,找到和相等的时候,就将中间剩下的部分二分,找到这个中间位置看是否满足,同时维护字典序最小.
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
int n;
ll a[maxn];
ll s[maxn];
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
s[i]=s[i-1]+a[i];
}
int p1=1,p2=0,p3=n;
int c1=-1,c2=-1,c3=-1;
while(p1+1<=p3+1-4)
{
while(p1<=p3-6&&s[p1]!=s[n]-s[p3-1])
{
while(p1<=p3-6&&s[p1]<s[n]-s[p3-1]) p1++;
while(p1<=p3-6&&s[p1]>s[n]-s[p3-1]) p3--;
}
if(p1>p3-6)
break;
p2=lower_bound(s+p1+2,s+p3-1,s[p1]+s[p1+1])-s;
if(s[p1]==s[p3-2]-s[p2+1]&&p3-p2>=4)
{
if(c1==-1)
{
c1=p1,c2=p2,c3=p3;
continue;
}
if(c1<p1)
break;
if(c2>p2||(c2==p2&&c3>p3))
{
c2=p2;
c3=p3;
}
}
p3--;
}
if(c1==-1)
printf("-1\n");
else
printf("%d %d %d\n",c1+1,c2+1,c3-1);
}
return 0;
}