http://acm.fzu.edu.cn/problem.php?pid=1914
题目大意是序列A(a1,a2,a3......an),序列B(b1,b2,b3......bn),且序列B由序列A生成(bi=a 1 +a 2 ,+…+a i (1≤i≤n)),若序列B内元素都为正数,则称序列A为一个正序列。
现在左移序列A内的元素0,1,2.....n-1次,产生n个新的序列:
A(0): a 1 ,a 2 ,…,a n-1 ,a n
A(1): a 2 ,a 3 ,…,a n ,a 1
…
A(n-2): a n-1 ,a n ,…,a n-3 ,a n-2
A(n-1): a n ,a 1 ,…,a n-2 ,a n-1
问{ A(0), A(1), …, A(n-2), A(n-1) }内有多少个正序列。
总体思想是先找到一个<=0的数 a i ,然后向前加( a i +a i-1 ),若小于等于0说明该元素(a i-1 )不可能放在序列首(因为已经不满足和为正数的要求)
这样向前循环遍历一遍序列就可找出所有不可放在序列首的元素。剩下的元素即是正序列的个数。
1
#include<stdio.h>
2
#include<stdlib.h>
3
#include<
string
.h>
4
int
p[
500001
], flag[
500001
];
5
int
main()
6
{
7
int
m , n;
8
int
i, index, ans, cas =
0
;
9
long
long
sum;
10
scanf(
"
%d
"
, &
m);
11
while
(cas <
m)
12
{
13
index = -
1
;
14
sum =
0
;
15
memset(flag,
0
,
sizeof
(flag));
16
scanf(
"
%d
"
, &
n);
17
for
(i =
0
;i < n;i++
)
18
{
19
scanf(
"
%d
"
, &
p[i]);
20
if
(p[i] <=
0
)
21
index =
i;
22
sum +=
p[i];
23
}
24
if
(index == -
1
)
25
{
//
都为正数 ,直接输出n
26
printf(
"
Case %d: %d\n
"
, ++
cas, n);
27
continue
;
28
}
29
if
(sum <=
0
)
30
{
//
和小于等于0,直接输出0
31
printf(
"
Case %d: 0\n
"
, ++
cas);
32
continue
;
33
}
34
flag[index] = -
1
;
35
sum =
p[index];
36
for
(i = (index -
1
+ n)%n; i != index; i = (i -
1
+ n)%
n)
37
{
38
sum +=
p[i];
39
if
(sum >
0
)
40
{
41
sum =
0
;
42
continue
;
43
}
44
flag[i] = -
1
;
45
}
46
i =
index;
47
sum +=
p[i];
48
while
(sum <=
0
)
49
{
50
flag[i] = -
1
;
51
i = (i -
1
+ n)%
n;
52
sum +=
p[i];
53
}
54
ans =
0
;
55
for
(i =
0
; i < n; i++
)
56
if
(flag[i] ==
0
)
57
ans++
;
58
printf(
"
Case %d: %d\n
"
, ++
cas, ans);
59
}
60
return
0
;
61
}

