题目描述
题意简单到令人发指!
序列A由N个整数组成,从中选出一个连续的子序列,使得这个子序列的和为正数,且和为所有和大于零的子序列中的最小值.
将这个值输出,若无解,输出no solution。
输入
第一行输入一个正整数N (2 < N < 50000)
第二行输入N个整数
输出
输出最小的正子段和
样例输入
3
-1 2 3
样例输出
1
思路
- 连续的子序列的和可以用sum[a] - sum[b]表示
- 符合题目的条件需要满足两个条件
- a > b
- sum[a] - sum[b] 尽可能的小
- 综上对sum[] 排序,满足1,2的就是答案
AC
#include<bits/stdc++.h>
#define ll long long
#define mem(a, b) memset(a, b, sizeof(a))
#define N 50005
#define P pair<ll, int>
using namespace std;
P sum[N];
int main() {
// freopen("in.txt", "r", stdin);
int n;
while (~scanf("%d", &n)) {
mem(sum, 0);
//构建pair
for (int i = 1; i <= n; i++) {
scanf("%lld", &sum[i].first);
sum[i].first = sum[i - 1].first + sum[i].first;
sum[i].second = i;
}
//对pair排序
sort(sum + 1, sum + 1 + n);
ll ans = 1e9;
if (sum[1].first > 0) ans = sum[1].first;
//排序之后保证后大于前,只要满足顺序关系就可以更新
for (int i = 2; i <= n; i++) {
//1 到 N的序列单独判断
if (sum[i].first > 0) ans = min(ans, sum[i].first);
// else continue;
if (sum[i].second > sum[i - 1].second && sum[i].first != sum[i - 1].first)
ans = min(ans, sum[i].first - sum[i - 1].first);
}
if (ans == 1e9) printf("no solution\n");
else printf("%d\n", ans);
}
return 0;
}