题目链接: https://vjudge.net/problem/34000/origin
题意 : 有n(10<n<=100 000)个正整数a[i] (a[i]<10 000) 组成的一个序列.给定整数S,求长度最短的连续序列,使他们的和大于或等于S(S <1e9).
Sample Input
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5
Sample output
2
3
分析:
只求和,可以先更新得到和序列,此时枚举左右端点(i,j)还是超时.注意到和序列是递增的,对于每个右端点我们要找到最大满足条件(s[j] - s[i] >= S)可以二分得到i,此时时间复杂度O(nlog(n))
可以进一步优化,若s[j]对应的i为x,那么s[j+1]对应的i一定大于等于x,也就说满足条件的i也是递增的,可以接着上次的i计算这次的i,也就最多只需找n次i;时间复杂度为O(n);
分析:
只求和,可以先更新得到和序列,此时枚举左右端点(i,j)还是超时.注意到和序列是递增的,对于每个右端点我们要找到最大满足条件(s[j] - s[i] >= S)可以二分得到i,此时时间复杂度O(nlog(n))
可以进一步优化,若s[j]对应的i为x,那么s[j+1]对应的i一定大于等于x,也就说满足条件的i也是递增的,可以接着上次的i计算这次的i,也就最多只需找n次i;时间复杂度为O(n);
#include <iostream>
#include <cstdio>
using namespace std;
int a[100100];
int main()
{
int n, s;
while(scanf("%d%d", &n, &s) != EOF)
{
a[0] = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
a[i] += a[i - 1];
}
int i = 1;
int ans = n + 1;
for(int j = 1; j <= n; j++)
{
if(a[i - 1] > a[j] - s) continue;
while(a[i] <= a[j] - s) i++;
ans = min(ans, j - i + 1);
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
for(int k = j; )
}
}
printf("%d\n", ans == n + 1 ? 0 : ans);
}
return 0;
}