简单记录一个原则,慎用浮点数比较。
给一个朋友忽悠了,去写讲解一下 AtCoder Beginner Contest。既然是讲课,备课肯定是必须的。
题目链接为https://atcoder.jp/contests/abc161/tasks/abc161_b。
We have held a popularity poll for N items on sale. Item i received Ai votes.
From these N items, we will select M as popular items. However, we cannot select an item with less than of the total number of votes.
If M popular items can be selected, print Yes
; otherwise, print No
.
1 ≤ M ≤ N ≤100
1 ≤ Ai ≤ 1000
Ai are distinct.
All values in input are integers.
Input is given from Standard Input in the following format:
N M
A1 ... An
If M popular items can be selected, print Yes
; otherwise, print No
.
4 1
5 4 2 1
Yes
There were 12 votes in total. The most popular item received 5 votes, and we can select it.
3 2
380 19 1
No
There were 400 votes in total. The second and third most popular items received less than of the total number of votes, so we cannot select them. Thus, we cannot select two popular items.
12 3
4 56 78 901 2 345 67 890 123 45 6 789
Yes
讲真,AtCoder Beginner Contest 这个级别比赛真心不难,比普及组第 4 题的难度略低,尤其是 A、B、C 这三题,基本没有涉及到算法方面。
但是很不幸,这题就翻车了。
错误情况如上图所示,有一个测试用例没有通过。当时就懵逼了,我去,这里都能翻车啊。
这题好简单啊。统计一下就好了。下面是我提交的代码。
#include
const int MAXN = 100+2;
int nums[MAXN];
int main() {
int n,m;
scanf("%d%d", &n, &m);
int sum=0;
for (int i=0; ipopular) {
cnt++;
if (cnt >= m) {
printf("Yes\n");
return 0;
}
}
}
printf("No\n");
return 0;
}
当时自己心里说别慌,我们仔细分析。仔细看了一下题目,可能的翻车原因有如下几个:
1、因为使用了,数组越界。查了一下代码,数据越界是不存在的。而且如果数据越界,给的反馈肯定不会是 WA。
2、由于使用了整数转换成浮点数,那么可能是出现了整数除以整数导致小数部分给省略。检查代码,所有整数转浮点数的时候,都已经使用隐式转换,不是这个问题。
我去,这下麻烦大了,不是小细节。我就有点晕了。马上拿出精神,开始写测试对拍程序,然后我们开始开心的拍啊拍。结果拍了十几分钟,没有问题出现。懵逼状态开始如下变化。
到,随着对拍时间持续,变成,最后到达。我的天哪,难道题目里有大 Boss。
我静下来,再次一行一行阅读了代码。看到比较的时候,突然灵感闪现。标准浮点数比较是需要用精度比较,而不能直接用符号比较的,因为涉及到精度问题。其他地方不可能出现问题的。好的,立马将代码改成整数比较。
#include
const int MAXN = 100+2;
int nums[MAXN];
int main() {
int n,m;
scanf("%d%d", &n, &m);
int sum=0;
for (int i=0; i=sum) {
cnt++;
if (cnt >= m) {
printf("Yes\n");
return 0;
}
}
}
printf("No\n");
return 0;
}
再次提交。绿色的 AC 出现。
苍天啊。果然是细节。特此记录。慎用浮点数比较。