PAT 1012. 数字分类 (20)

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

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

要求


时间限制 400 ms
内存限制 65536 kB
代码长度限制 8000 B
判题程序 Standard
作者 CHEN, Yue

题目

给定一系列正整数,请按要求对数字进行分类,并输出以下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”。

输入样例1:
13 1 2 3 4 5 6 7 8 9 10 20 16 18
输出样例1:
30 11 2 9.7 9
输入样例2:
8 1 2 4 5 6 7 9 16
输出样例2:
N 11 2 N 9

分析

题目读完的感觉是:不是很难,细心一点应该就没问题了。分析主要可能出错的地方:

  • 输出格式,注意每个数后面的空格,非数字的N,最后一个没有空格,A4小数点保留1位 ;
  • 注意判断数字不存在的方法,比如A4,如果A4的个数为0,直接可以输出N,不必计算平均值;
  • 唯一可能复杂一点就是A2了,错误求和注意符号之类的。
    考虑完这些提交以后总是有两个1分测试点不对,一直揪着程序看,也没有看出哪个数不对,索性测试了一下1-16这16个数,发现A5输出的居然是15.
    原来:
1
2
3
4
5
6
7
8
9
10
11
if(num%5==0&&num%2==0){  // 整除5且为偶数的数
if(A1==-1)A1=num; // 第一个满足A1条件的数
else A1=A1+num; // 求和
}
else if(num%5==1)inA2.push_back(num); // 存储
else if(num%5==2)A3++; // 个数自增
else if(num%5==3){
A4=A4+num;
countOfA4++; // 记录个数,用于求平均值
}
else inA5.push_back(num);

注意最后一个else,问题就出在这里,最后还是不细心导致的问题,第一个if处if(num%5==0&&num%2==0) 当num被5整除,切为偶数时,后面的三个else if分别是num除5余数分别是1,2,3时,最后为了省事,直接写了一个else。
问题就出在这个else上,如果num是被5整除的奇数也会进入这个else,最终导致程序结果错误。

代码

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
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>
#include <algorithm>

using namespace std;

bool compare(int a,int b){ // 降序排列
return a>b;
}

int main(){
int num,n;
float A1=-1,A2=0,A3=0,A4=0,A5=0; // 分别存储A1-A5的值 //注意将A1初始化为了-1 用于判断个数是否为零
int countOfA4=0,countOfA2=0; // 记录A4,A2的数量
vector<int> inA5; // 存储满足A5条件的数
vector<int> inA2; // 存储满足A2条件的数
cin>>n;
while(n>0){
cin>>num;
if(num%5==0&&num%2==0){ // 整除5且为偶数的数
if(A1==-1)A1=num; // 第一个满足A1条件的数
else A1=A1+num; // 求和
}
else if(num%5==1)inA2.push_back(num); // 存储
else if(num%5==2)A3++; // 个数自增
else if(num%5==3){
A4=A4+num;
countOfA4++; // 记录个数,用于求平均值
}
else if(num%5==4)inA5.push_back(num); // 不写 else if只写else 就错了
/*
因为第一个条件是num%5==0&&num%2==0,后续的条件也只是
判断了余数分别为1,2,3的情况,如果直接草率的写上else,那么
整除5的奇数和余数为4的数,都会被当做满足A5的数!
所以保险起见,尽量不要使用else来判断,只有在判断条件只有
一个的时候用else一般不会错,判断条件较多时,不如直接写出所
有的else if条件。
*/

n--;
}
if(A1==-1)cout<<"N "; // 如果没有满足条件的数,输出 N 还有空格
else cout<<A1<<" "; // A1

countOfA2=inA2.size();
for(int temp=0;temp<countOfA2;temp++){
A2=A2+pow(-1,temp)*inA2[temp]; // 交错求和
}
if(inA2.size()==0)cout<<"N ";
else cout<<A2<<" "; // A2

if(A3==0)cout<<"N ";
else cout<<A3<<" "; // A3

if(countOfA4==0)cout<<"N "; // 没有满足条件的数
else cout<<setiosflags(ios::fixed)<<setprecision(1)<<A4/countOfA4<<" "; // 输出一位小数

sort(inA5.begin(),inA5.end(),compare); // 将满足条件的数降序排列

if(inA5.size()==0)cout<<"N";
else cout<<inA5[0]; // 取出首位元素即是最大的

return 0;
}
坚持原创技术分享,您的支持将鼓励我继续创作!