201909 CSP 2 小明种苹果(续)

问题描述
小明在他的果园里种了一些苹果树,这些苹果树排列成一个圆。为了保证苹果的品质,在种植过程中要进行疏果操作。为了更及时地完成疏果操作,小明会不时地检查每棵树的状态,根据需要进行疏果。检查时,如果发现可能有苹果从树上掉落,小明会重新统计树上的苹果个数(然后根据之前的记录就可以判断是否有苹果掉落了)。在全部操作结束后,请帮助小明统计相关的信息。
输入格式
从标准输入读入数据。
第1行包含一个正整数N,表示苹果树的棵数。
第1+i行(1≤i≤N),每行的格式为mi,ai1,ai2,…,aimi。其中,第一个正整数mi表示本行后面的整数个数。后续的mi个整数表示小明对第i棵苹果树的操作记录。若aij(1≤i≤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=|Ai|Drop(Pred(Ai)∧Drop(Ai)∧Drop(Succ(Ai))|
其中,Drop(Ai)表示苹果树Ai是否发生苹果掉落的情况,Pred(Ai)表示Ai的前一棵树Ai−1(如果i>1)或者AN(如果i=1),Succ(Ai+1)表示Ai的后一棵树Ai+1(如果i 或者A1(如果i=N)。
样例1输入
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解释
全部操作结束后,第1棵树上剩下的苹果个数为74−7−12−5=5074−7−12−5=50,第2棵为59−4=5559−4=55,第3棵为60−2=5860−2=58,第4棵为59−0=5959−0=59。因此T=50+55+58+59=222T=50+55+58+59=222。
其中,第3棵树在第2次统计之前剩下的苹果个数为76−5−10=61>6076−5−10=61>60,因此发生了苹果掉落的情况。可以检验其他的树没有这种情况,因此D=1D=1。
没有连续三棵树都发生苹果掉落的情况,因此E=0。
样例2输入
5
4 10 0 9 0
4 10 -2 7 0
2 10 0
4 10 -3 5 0
4 10 -1 8 0
样例2输出
39 4 2
样例2解释
第1、2、4、5棵树发生了苹果掉落的情况,因此D=4。其中,连续三棵树都***发生苹果掉落情况的有(5,1,2)和(4,5,1),因此E=2。
子任务***
mi≤1000,对所有 1≤i≤N
|aij|≤106,对所有 1≤i≤N,1≤j≤m;
编号 N maxmi
1,2 3 2
3,4 10 10
5,6 10 100
7,8 100 100
9,10 1000 1000
提示
如果你的程序没有实现统计D和E的功能,请按照D=0,E=0输出结果,这样如果T的统计正确能够得到一部分分数。
如果你的程序没有实现统计E的功能,请按照E=0输出结果,这样如果T和D的统计正确能够得到一部分分数。

设计思路:
1. 在计算每棵树的操作前先接收操作轮数m,然后依次接收当前苹果数和疏果数存入a
2. 如果a>0,则和p比较判断是否有掉落,有掉落则t数组对应位置更新(表示这棵树掉落了,并且更新p=a
3. 如果a<=0则直接计算剩余苹果数
4. 计算剩余总的苹果数,重置p,开始下一个苹果树的操作
5. 全部操作结束后,计算掉落的棵数
6. 计算相邻组数

然后是代码

#include 
using namespace std;
int N, m, T, D, E;//苹果棵数,疏果轮数,剩下苹果总数,发生苹果掉落的苹果树棵数,相邻连续三棵树发生苹果掉落情况的组数
int a, i, t[1001] = { 0 }, j, p;//a用于接收每次疏果数,i为树的编号,t数组用于记录每棵树是否有掉落,j为疏果操作轮数,p计算一棵树的剩余果数
void check(int t[])
{
	for (int i = 1; i <= N-2; i++)
	{
		if (t[i] && t[i + 1] && t[i + 2])
			E++;
	}//前N-2棵树的相邻情况
	if (t[N - 1] && t[N] && t[1])
		E++;
	//倒数第二棵+倒数第一棵+第一棵
	if (t[N] && t[1] && t[2])
		E++;
	//倒数第一棵+第一棵+第二棵
}//判断是否连续三组都有掉落
int main()
{
	cin >> N;
	for (i = 1; i <= N; i++)
	{
		cin >> m;//接受第i棵树的操作轮数
		for (j = 1; j <= m; j++)
		{
			cin >> a;//接收当前苹果个数或第j轮的疏果数
			if (a > 0)
			{
				if (a < p)
				{
					t[i] = 1;
				}
				p = a;
			}//判断是否有苹果掉落
			//如果有掉落则t数组中该苹果树代表的位置变为一,表示有掉落
			else
			{
				p += a;//计算前j轮操作后苹果数
			}//没有掉落 则继续计算苹果数
		}
		T = T + p;//计算剩余苹果数
		p = 0;//重置p
	}
	for (int i = 1; i <= N; i++)
	{
		if (t[i])
			D++;
	}
	check(t);//计算相邻组数
	cout << T << ' ' << D << ' ' << E << ' ' << endl;//输出数据
	return 0;
}

小结:一开始在判断a>0的情况时没有考虑统计了果数却没有掉落的情况,然后又没有考虑一棵树出现多次掉落的情况,考虑过后修改提交通过了

你可能感兴趣的:(试题思路,csp)