【问题描述】
小明在他的果园种了一些苹果树,这些苹果树排列成一个圆。为了保证苹果的品质,在种植过程中要进行疏果操作。为了更及时地完成疏果操作,小明会不时地检查每棵树的状态,根据需要进行疏果。检查时,如果发现可能有苹果从树上掉落,小明会重新统计树上的苹果个数(然后根据之前的记录就可以判断是否有苹果掉落了)。在全部操作结束后,请帮助小明统计相关的信息。
【输入格式】
从标准输入读入数据。
第1行包含一个正整数N,表示苹果树的棵数。
第1+i行(1≤i≤N),每行的格式为mi, ai1, ai2, …, ai, mi。其中,第一个正整数mi表示本行后面的整数个数。后续的mi个整数表示小明对第i棵苹果树的操作记录。若aij(1≤j≤mi)为正整数,则表示小明进行了重新统计该棵树上的苹果个数的操作,统计苹果个数为aij;若为零或负整数,则表示一次疏果操作,去掉苹果个数是aij的绝对值。
输入保证一定是正确的,满足:
ai1>0,即对于每棵树的记录,第一个操作一定是统计苹果个数(初始状态,此时不用判断是否有苹果掉落);每次疏果操作保证操作后树上的苹果个数仍为正。
【输出格式】
输出到标准输出。
输出只有一行,包含三个整数T、D、E。其中,
- T 为全部疏果操作结束后所有苹果树上剩下的苹果总数(假设每棵苹果树在最后一次统计苹果个数操作后苹果不会因为疏果以外的原因减少;
- D 为发生苹果掉落的苹果树的棵数;
- E 为相邻连续三棵树发生苹果掉落的组数。
对于第三个统计量的解释:N棵苹果树A1,A2,…,AN排列成一个圆,那么A1与A2相邻,A2与A3相邻,…… ,AN−1与AN相邻,AN与A1相邻。如果Ai−1,Ai,Ai+1这三棵树都发生了苹果掉落的情况,则记为一组。形式化的,有
E=\mid\left\{A_{i} \mid \text { Drop }\left(\operatorname{Pred}\left(A_{i}\right)\right) \wedge \operatorname{Drop}\left(A_{i}\right) \wedge \operatorname{Drop}\left(\operatorname{Succ}\left(A_{i}\right)\right)\right\} \mid
其中, Drop(Ai) 表示苹果树 Ai 是否发生苹果掉落的情况, Pred(Ai) 表示 Ai的前一棵树 Ai−1( 如果 i>1) 或者 AN( 如果 i=1 ) ,Succ(Ai) 表示 Ai 的向一棵树 Ai+1( 如果 i<N) 或者 A1 (如果 i=N )。
【样例输入】
1
2
3
4
5
4
4 74 -7 -12 -5
5 73 -8 -6 59 -4
5 76 -5 -10 60 -2
5 80 -6 -15 59 0
【样例输出】
1
222 1 0
【题目截图】
【题解】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; //苹果树棵树
int m, a; //m:每棵树的操作次数, a:每次操作的情况
int n; //n:记录当前苹果树人工操作后的苹果数
int T = 0; //全部操作完后的苹果总数,初始为0
int D = 0; //发生苹果掉落情况的组数,初始为0
int E = 0;//相邻连续三棵树发生苹果掉落的组数
cin >> N;
int flag[N]; //标记苹果树是否有掉落
for(int i = 0; i < N; i++){
flag[i] = 0;
cin >> m;
for(int j = 0; j < m; j++){
cin >> a;
if(j == 0){
T += a; //统计苹果树
n = a; //当棵苹果树上的苹果情况
}
else if(a <= 0){
T += a;
n += a;
}
else if((a > 0) && (n > a)){
flag[i] = 1; //树i发生苹果掉落
T = T - (n - a); //减去掉落的苹果数
n = a; //更新n为a
}
}
}
for(int i = 0; i < N; i++){
if(flag[i] == 1)
D++; //统计掉落的苹果棵数
if(i == 0) //边界情况:开头的树
{
if((flag[i] == 1) && (flag[i+1] == 1) && (flag[N-1] == 1))
E++;
}
else if(i == (N - 1)) //边界情况:结尾的树
{
if((flag[i] == 1) && (flag[i-1] == 1) && (flag[0] == 1))
E++;
}
else //if((i != 0) || (i != N - 1))的情况
{
if((flag[i] == 1) && (flag[i-1] == 1) && (flag[i+1] == 1))
E++;
}
}
cout << D << " " << E << endl;
return 0;
}