本题是浙江理工大学ACM入队200题第二套中的B题

我们先来看一下这题的题面.


由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例.

  • 样例相当于给你举了个具体的例子,可以帮助你更好的理解题目
  • 样例会告诉你输入和输出的格式,你必须要在程序里以这样的格式输入和输出,否则会出问题
  • 样例可以在你本地写完代码之后用作测试,来检查你的代码能否正常地运行(不过样例运行正确并不代表完全对了,可能输入其他的数据会出现别的问题)

题面

题目描述

输入3个整数,求出平均值,保留3位小数

输入

输入3个整数

输出

输出平均值,保留3位小数

样例输入

2 3 4

样例输出

3.000


常见错误思路

这题看起来非常简单,相信每一位朋友看完题面以后都会有一下的思路:

  1. 从输入流读入这3个整数
  2. 根据平均值的定义,先把3个整数加起来,然后除以3
  3. 将算得的结果以3位小数的格式输出(什么,你说你不会保留3位小数?先往下看后面会给出的)

于是有些朋友们给出了如下的代码(局部):

int sum = a + b + c; // 利用sum变量保存三整数和
double ave = sum / 3; // 根据平均值的定义,计算平均值
printf("%.3lf", ave); // 利用printf函数输出结果(lf前的.3表示只显示3位小数,类似的显示两位就写%.2lf,简单吧)

发现能成功通过样例,于是自信满满地提交了上去,然后迎接他的是答案错误.

可是,难道平均值不是这么求的嘛?这和数学上求解平均值的方法完全一致啊,哪里会出现问题呢?

问题就出在这些朋友完全用数学来理解C语言的运算符了.当我们把输入改成2 2 4的时候,你就会发现程序的输出是2.000而不是我们所期待的2.666.

常见错误原因解析

首先,我们明白在C中,每个数据都是具有数据类型的,比如1,2,3这种的数据类型是int,而1.1,1.0这种的数据类型是double,并且在C中各个数据类型之间还是有一定的界限的,int和double还是有一定区别的,但是我们可以对它们进行类型转换:

  • int可以转为double,此时会在原本的整数之后补上全为0的小数部分
  • double可以转为int,此时会直接去掉原本实数的小数部分,只剩下整数部分(不是四舍五入,也不是向下取整,而是直接去掉)

然后,我们回到这道题来,为何2 2 4的输出是2.000呢?稍加观察不难发现,我们的错误结果正好是正确答案的整数部分.而后面的小数部分非常像int转为double时出现的全为0的小数部分.

那么,导致此处错误的真相也已然呼之欲出了,我们写的sum / 3所得的结果是int类型(由此才只有正确答案的整数部分),随后我们把它赋值给double类型的ave变量,触发了自动转型,将其变为了一个double类型的实数,也就是我们看到的2.000了.

那为何会如此呢?这是因为在C中,除法运算符所得结果的类型是两个操作数中精度最高的类型,精度顺序大致如下:

double > long long > int > short > char

当我们将一个int型的数据去除另一个int型的数据时,根据上述类型决定规则,我们得到的结果是一个int型的数据,由此导致了上述的问题.

这个问题在实际写代码中还是比较容易犯的,一不小心就会失误直接将两个int类型的数据相除,所以各位朋友们一定要注意奥!

解决方案

明白了问题所在,如何解决呢?非常简单,既然返回的是精度最高的类型,那么我们就将其中一个数据改为double类型呗,此处有多种解决方法:

  • double ave = (double)sum / 3; // 利用强制转型运算符将第一个操作数转为double

  • double ave = sum * 1.0 / 3; // 通过乘法(其结果类型决定方式与除法一致)间接将第一个操作数转为double(注意优先级问题,不要写成sum / 3 * 1.0)

  • double ave = sum / 3.0; // 将常数3写成实数形式

  • double sum = a + b + c; // 直接将sum定义为double类型

  • ...

上述几种方法在此处均可行,但在别的地方受限于具体情况可能只能使用其中的一种或几种,最好都理解并掌握(原理都是将一个操作数改为double类型)

参考代码

下面给出了我自己做这道题时候的完整代码:

(仅作为参考,一定要自己写一下奥,作弊没意思,害人又害己)

#include <stdio.h>

int main()
{
int a, b, c; // 定义三个变量以储存输入的三个数
scanf("%d%d%d", &a, &b, &c); // 输入三个数
int sum = a + b + c;// 利用sum变量保存三整数和
double ave = sum / 3.0; // 根据平均值的定义,计算平均值,并使结果为实数
printf("%.3lf", ave); // 利用printf函数输出结果(lf前的.3表示只显示3位小数,类似的显示两位就写%.2lf,简单吧) return 0;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

这篇题解就到这里了,各位朋友如果有问题欢迎到acm成员群中提问哦!

「浙江理工大学ACM入队200题系列」问题 B: 零基础学C/C++12——求平均值的更多相关文章

  1. 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积

    本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...

  2. 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解

    本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  3. 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数

    本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...

  4. 「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断

    本题是浙江理工大学ACM入队200题第八套中的K题 我们先来看一下这题的题面. 题面 题目描述 任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO; 例如,字符A的ASCI ...

  5. 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路

    本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...

  6. 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......

    本题是浙江理工大学ACM入队200题第五套中的L题 我们先来看一下这题的题面. 题面 题目描述 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13,-- 计算这个数列的前n项和.注意: ...

  7. 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)

    本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...

  8. 「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转

    本题是浙江理工大学ACM入队200题第二套中的H题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  9. [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念

    上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...

随机推荐

  1. KubeEdge:下一代云原生边缘设备管理标准DMI的设计与实现

    摘要:KubeEdge设备管理架构的设计实现,有效帮助用户处理设备数字孪生进程中遇到的场景. 本文分享自华为云社区<KubeEdge:下一代云原生边缘设备管理标准DMI的设计与实现>. 随 ...

  2. setContentView源码分析

    当我们在Activity中调用setContentView,它到底做了什么呢 override fun onCreate(savedInstanceState: Bundle?) { super.on ...

  3. iOS 组件化及二进制化的探索

    组件化的优缺点 组件化的拆分 组件与组件之间如何进行通讯(路由) 从Cocopods拉取代码的过程 远程索引库里很多的.spec文件,该文件记录了很多内容,如用户名,框架名称,描述,框架的地址 Pod ...

  4. KingbbaseES V8R6集群维护案例之---集群之间数据迁移

    案例说明: 生产环境是集群环境,测试环境是集群,现需要将生产环境的数据迁移到测试集群中运行,本文档详细介绍了从集群环境迁移数据的操作步骤,可以作为生产环境迁移数据的参考. 适用版本: Kingbase ...

  5. 跟羽夏学 Ghidra ——导航

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...

  6. 《Java基础——选择语句》

    Java基础--选择语句       1. if语句; 规则: 1. 首先计算表达式的值. 2. 若表达式为真,则执行对应语句,为假则不执行.   格式一: if(表达式) 语句;//多个语句可用{} ...

  7. Java的lamda表达式/函数式接口/流式计算

    在我们看他人code的时候经常会看到,可能会经常看到lambda表达式,函数式接口,以及流式计算.在刚接触这些新功能时,也觉得真的有必要吗?但是现在写多了,发现这个功能确实能简化代码结构,提升编码效率 ...

  8. kubectl top命令

    kubectl top命令可显⽰节点和Pod对象的资源使⽤信息,它依赖于集群中的资源指标API来收集各项指标数据.它包含有node和pod两个⼦命令,可分别⽤于显⽰Node对象和Pod对象的相关资源占 ...

  9. Solutions:Elastic SIEM - 适用于家庭和企业的安全防护 ( 四)

  10. 部署文件:filebeat->kafka集群(zk集群)->logstash->es集群->kibana

    该压缩包内包含以下文件: 1.install_java.txt 配置java环境,logstash使用 2.es.txt 三节点的es集群 3.filebeat.txt 获取日志输出到kafka集群 ...