HDU-4193 Non-negative Partial Sums
2016-04-28 15:42
302 查看
题意:n个数有多少种移位方式使得从第一个数往后加加到任意位置时和都不小于0,移位就是将第一个数字放到最后一个,1<=n<=1 000 000.
一开始尝试用st表和线段树找区间和得最小值,结果是超内存。这个题没有那个复杂,从第n个数开始往前加,如果加到某个数字和是负数,那么这个数字肯定不能作为第一个数字,如果是正数那么这一段区间的和不会影响前面的区间,可以把和置为0,从前一个数重新开始加,因为是循环移位,最前面数字的加和可能会影响后面的数字,所以扫描两遍数组,最后扫描标记数组,一共有多少个数字可以作为第一个数。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000000;
int d[MAXN], p[MAXN];
int main() {
int n, i, j;
while(~scanf("%d", &n) && n) {
for(i = 0; i < n; i++)
scanf("%d", &d[i]);
int is = 0, s = 0;
memset(p, -1, sizeof(p));
for(i = n-1; is < 2; i = (i - 1 + n) % n) {
is += !i;
s += d[i];
if(s < 0)
p[i] = 0;
else s = 0;
}
int ans = 0;
for(i = 0; i < n; i++)
ans -= p[i];
printf("%d\n", ans);
}
return 0;
}
一开始尝试用st表和线段树找区间和得最小值,结果是超内存。这个题没有那个复杂,从第n个数开始往前加,如果加到某个数字和是负数,那么这个数字肯定不能作为第一个数字,如果是正数那么这一段区间的和不会影响前面的区间,可以把和置为0,从前一个数重新开始加,因为是循环移位,最前面数字的加和可能会影响后面的数字,所以扫描两遍数组,最后扫描标记数组,一共有多少个数字可以作为第一个数。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000000;
int d[MAXN], p[MAXN];
int main() {
int n, i, j;
while(~scanf("%d", &n) && n) {
for(i = 0; i < n; i++)
scanf("%d", &d[i]);
int is = 0, s = 0;
memset(p, -1, sizeof(p));
for(i = n-1; is < 2; i = (i - 1 + n) % n) {
is += !i;
s += d[i];
if(s < 0)
p[i] = 0;
else s = 0;
}
int ans = 0;
for(i = 0; i < n; i++)
ans -= p[i];
printf("%d\n", ans);
}
return 0;
}
相关文章推荐
- 【HDU 5366】The mook jong 详解
- 【HDU 2136】Largest prime factor 详细图解
- 【HDU 1568】Fibonacci 数学公式 详解
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- HDU 1016 Prime Ring Problem
- HDU 1017 A Mathematical Curiosity