【欢迎关注微信公众号:计算机黑科学大全,对话框回复:PAT乙级真题】获取全部真题详解及代码示例 个人博客地址:https://mzwang.top
本题的基本要求非常简单:给定 N 个实数,计算它们的平均值。但复杂的是有些输入数据可能是非法的。一个“合法”的输入是 [−1000,1000] 区间内的实数,并且最多精确到小数点后 2 位。当你计算平均值的时候,不能把那些非法的数据算在内。
输入第一行给出正整数 N(≤100)。随后一行给出 N 个实数,数字间以一个空格分隔。
对每个非法输入,在一行中输出 ERROR: X is not a legal number,其中 X 是输入。最后在一行中输出结果:The average of K numbers is Y,其中 K 是合法输入的个数,Y 是它们的平均值,精确到小数点后 2 位。如果平均值无法计算,则用 Undefined 替换 Y。如果 K 为 1,则输出 The average of 1 number is Y。
题目来源:PAT乙级1054 作者:CHEN, Yue 单位:浙江大学
本题如果用分类讨论法将会很复杂,利用sscanf()函数与sprintf()函数将大大简化问题。判断一个输入数据是否为合法的过程如下:
输入数据到字符数组str1中;将字符数组str1的内容以"%lf"的格式写入temp(temp为double型)中;把temp中的数据以"%.2lf"的格式写到str2字符数组中;比较字符数组str1中的字符是否与str2中的相应字符相等;若4中相等且temp是 [−1000,1000] 区间内的实数则输入数据合法,否则不合法。题目明确要求如果 K 为 1,则输出 The average of 1 number is Y,注意此处输出语句中的number,当k>1时输出语句应中应为numbers。但是下面的平均值输出都是numbers。
以上可灵活应用。
小提示:请将以下代码保存为.cpp格式(C++程序)左右滑动代码以查看完整代码(复制本文链接到电脑端浏览效果更佳)
#include <cstdio> #include <cstring> #include <cmath> using namespace std; int Str_Cmp(char str1[],char str2[]); int main() { int n; scanf("%d",&n); int k = n; double sum = 0.0; char str1[50],str2[50]; //数组长度不能太短,否则会出现运行时错误 for(int i = 0; i < n; i++){ double temp; scanf("%s",str1); sscanf(str1,"%lf",&temp); //将字符数组str1的内容以"%lf"的格式写入temp中 sprintf(str2,"%.2lf",temp); //把temp以"%.2lf"的格式写到str2字符数组中 if(fabs(temp) <= 1000&&!Str_Cmp(str1,str2)){ sum += temp; } else{ k--; //合法数减1 printf("ERROR: %s is not a legal number\n",str1); } } if(!k){ printf("The average of 0 numbers is Undefined"); } else if(k == 1){ //题目明确说明k为1时要特殊对待,即把numbers改为number printf("The average of 1 number is %.2lf",sum); } else{ printf("The average of %d numbers is %.2lf",k,sum / k); } return 0; } //重写字符串比较函数 int Str_Cmp(char str1[],char str2[]) { int len1 = strlen(str1); for(int i = 0; i < len1; i++){ //只需按str1字符串的长度比较即可,str2多出的部分不必比较 if(str1[i] != str2[i]){ return 1; } } return 0; }