本题是浙江理工大学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. Aoac唤醒的软件方案

    Aoac唤醒 这篇文章包含了Win10下的Aoac唤醒和Win11下的Aoac唤醒的不同地方,在结尾处: 从Win10时代开始,通过软件来唤醒机器是一个很常见的事情了,但是很少有文档去将如何通过AOA ...

  2. centOS7.x修改root密码

    方法一: 在开机的时候选中这一行(注意光标要进入虚拟机),然后按下e键 然后找到这一行(linux 16开头的)其中的ro,将其改为 rw init=sysroot/bin/sh 按ctrl+x执行 ...

  3. 第九十九篇:JS闭包

    好家伙,总是要来的,去面对那些晦涩难懂的原理,它就在那里,等着我去搞定它 首先我要去补充一些最基本的概念, 1.什么是内存? 新华字典永远的神, 但这个解释显然不够   去看看百度百科: 内存: CP ...

  4. KingbaseES 绑定变量窥探机制

    概述: 对于数据严重倾斜的,极端如以下例子,不同的传入值,可能执行计划不同,制定执行计划时,就要求知道变量的值.对于绑定变量的情况,我们知道Oracle 有 _optim_peek_user_bind ...

  5. 当 SQL DELETE 邂逅 Table aliases,会擦出怎样的火花

    开心一刻 晚上,女儿眼噙泪水躺在床上 女儿:你口口声声说爱我,说陪我,却天天想着骗我零花钱,你是我亲爹吗? 我:你想知道真相 女儿:想! 我:那你先给爸爸两百块钱! 环境准备 MySQL 不同版本 利 ...

  6. 华南理工大学 Python第2章课后小测-1

    1.(单选)"abc"的长度是3,"老师好"的长度是多少?(本题分数:4)A) 1B) 3C) 6D) 9您的答案:B  正确率:100%2.(单选)下面代码的 ...

  7. Promtail 配置文件说明

    转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247492163&idx=1&sn=56b26aa387 ...

  8. KVM 下如何关闭 virbr0

    安装KVM 后都会发现网络接口里多了一个叫做 virbr0 的虚拟网络接口: 这是由于安装和启用了 libvirt 服务后生成的,libvirt 在服务器(host)上生成一个 virtual net ...

  9. 使用工具SecureCRT通过ssh远程连接Windows server 2019

    Windows Server 2019 开通SSH Server服务 在需要安裝的ws2019开启powershell,执行安装 openssh server 指令 Add-WindowsCapabi ...

  10. 使用docker-compose部署SonarQube

    sonarqube 安装 1.系统配置,避免启动问题 # 系统配置,避免启动问题 echo "vm.max_map_count=262144" >> /etc/sysc ...