求前缀和,然后升序排序。排序后相邻两个前缀和只差越小,比如prefixSum[i+1],假设他原来坐标是n,和prefixSum[i],假设他原来坐标是m,他俩差越小,则表明区间(m,n]之间的正整数和越小,前提是n>m。还有排序的时候如果有多个前缀和相等,则把下标大的放在前边,下标小的放后边。
比如输入数据:
4
0 4 1 -1
自己写一下就知道为啥那样排序了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct node
{
LL index,sum;
};
const int MAXN = 50010;
int num[MAXN];
node prefixSum[MAXN];
bool cmp(const node& a, const node& b)
{
if(a.sum != b.sum)
return a.sum < b.sum;
else
return a.index > b.index;
//return a.sum < b.sum;
}
int main()
{
//freopen("51nod_Problem_1065_Test_16_In.txt","r",stdin);
ios::sync_with_stdio(false);
int n;
cin >> n;
memset(prefixSum,0,sizeof(prefixSum));
for(int i = 1; i <= n; ++i)
{
cin >> num[i];
prefixSum[i].index = i;
prefixSum[i].sum = prefixSum[i-1].sum+num[i];
}
sort(prefixSum,prefixSum+1+n,cmp);
LL der = 1LL<<60;
for(int i = 1; i <= n; ++i)
{
if((prefixSum[i].sum-prefixSum[i-1].sum) < der && (prefixSum[i].sum-prefixSum[i-1].sum) > 0 && (prefixSum[i].index > prefixSum[i-1].index))
der = prefixSum[i].sum-prefixSum[i-1].sum;
}
cout << der << endl;
return 0;
}