PAT乙级真题解析:数字分类(1012)题目+解析+源码(C++版)

题目描述

给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字:

A1 = 能被5整除的数字中所有偶数的和;
A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3-n4…;
A3 = 被5除后余2的数字的个数;
A4 = 被5除后余3的数字的平均数,精确到小数点后1位;
A5 = 被5除后余4的数字中最大数字。

输入描述:

每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N,随后给出N个不超过1000的待分类的正整数。数字间以空格分隔。

输出描述:

对给定的N个正整数,按题目要求计算A1~A5并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。若其中某一类数字不存在,则在相应位置输出“N”。

输入例子:

13 1 2 3 4 5 6 7 8 9 10 20 16 18

输出例子:

30 11 2 9.7 9

题目解析:
首先观察题目可以得到以下两个有用的信息:

  1. 都是正整数,不会出现负数
  2. 一共需要输出5个数字
  3. 输出的数字都与“……能被 5 整除的数……”有关

所以我们需要用(至少)五个变量去保存输出的结果,我们暂时将他们命名为:

int c1=0, c2=0, c3=0, c5=0;
float c4=0; // 题目要求精确到小数点后1位,所以采用浮点数

以上都是我们看到题目第一眼能做出的判断,接下来我们来细看题目,首先

A​1 = 能被 5 整除的数字中所有偶数的和

解释:如果有一个数x,x除以5的余数值为0(即为偶数),就做一次记录(给将这个数x累加给c1)。
将上面这句话转换成代码:

if(x%5 == 0){
	c1 = c1 + x
}

A ​2 ​​ = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n ​1 ​​ −n ​2 ​​ +n ​3 ​​ −n ​4 ​​ ⋯;

这里交错求和的意思就是:一列数字,对奇数位的数字进行加运算,对偶数位的数字进行减运算。求和我们都会,可是如何交错求和呢?如何在不改变数字大小的情况下控制数字的符号呢?
在小学二年级我们就学过,给一个数乘“-1”会改变这个数字的符号,乘“1”数字不会变。
所以我们给奇数位乘“1”,给偶数位乘“-1”,就得到了如下代码。(可能有点烧脑,需要思考一下为什么这样写)

if(x%5 == 1) {
	int i = 1; // i变量是用来改变数字符号的,由于第一个数为正数,所以i的初始值为1
	c2 = c2 + (i*x);
	i = -i; // 这样可以使i在奇数位的时候为1,偶数位的时候为-1
}

A3 = 被5除后余2的数字的个数;

这个很简单,直接上代码

if(x%5 == 2) {
	c3 = c3 +1;
}

A4 = 被5除后余3的数字的平均数,精确到小数点后1位;

这里要想得到平均数我们需要记录两个值,

  1. 满足条件的数的总和
  2. 满足条件的数的个数

所以需要再声明一个变量,来记录满足条件的数的个数,最后输出的时候只需要计算出平均值就可以输出了。

int c4Num = 0;

if(x%5 == 3) {
	c4 = c4 + x; //计算满足条件的数的和
	c4Num= c4Num+1 ; //计算满足条件的数的个数
}

A5 = 被5除后余4的数字中最大数字。

找出最大值,这应该是我们最拿手的。

if(x%5 == 4) {
	if(x > c5) { // c5的初始值为0,因为题目中出现的所有数都会大于0,不会出现小于等于零的情况
		c5 = x; // 保存当前遇到的最大值
	}
}

已经到这一步啦!剩下的就是按题目条件输出就可以啦!
我们将所有的除余判断合并成一个条件语句,采用switch/case可以大大减少代码行数。
这里我们要注意题目的第四句话 “精确到小数点后1位”
在c++输出的语法中:

fixed 代表用一般的方式输出浮点数,而不是科学计数法
setprecision(n) 中的变量n可控制输出流显示浮点数的数字个数

所以 “精确到小数点后1位” 用代码就可以表示为

cout<<fixed<<setprecision(1)<<c4/c4Num // c4/c4Num为我们计算出的平均值

到这里!整个程序的基本逻辑我们已经完全清楚了,剩下的就是细节问题了!再次检查题目,最后附上源代码!!!

源代码:

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
	int c1=0, c2=0, c2Num=0, c3=0, c4Num=0, c5=0;
	float c4=0;
	int n,x,i=1;
	cin>>n;
	while(n--){
		cin>>x;
		switch(x%5){
			case 0:if(x%2==0) c1+=x; break;
			case 1:c2Num++; c2+=(i*x);i=-i; break;
			case 2:c3++; break;
			case 3:c4+=x; c4Num++; break;
			case 4:if(x>c5) c5=x; break;
		}
	}
	(c1>0)?(cout<<c1<<" "):(cout<<"N ");
	(c2Num!=0)?(cout<<c2<<" "):(cout<<"N ");
	(c3>0)?(cout<<c3<<" "):(cout<<"N ");
	(c4>0)?(cout<<fixed<<setprecision(1)<<c4/c4Num<<" "):(cout<<"N ");
	(c5>0)?(cout<<c5):(cout<<"N");
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值