人无完人,我只是一位C++的初学者,并不是一位专业的C++软件工程师,如果本篇文章有一些细微的错误或者是您有什么好的方法也希望您可以在本文下面评论,我会认真阅读并考虑采纳的。
事情de起因
由于我看我在OpenJudge中,1.3部分已经刷的差不多了,我便想着全部做完,下图是我做完1.3部分后的一张完成后的结算画面:

but,做这些题的时候一直都很痛苦,一般情况下都会Wrong Answer好几遍才能过。
以下是我做题时范的一些典型错误:
题目10
内容:对于阻值为r1和r2的电阻,其并联电阻阻值公式计算为:R = 1/(1/r1 + 1/r2)。输入两个电阻阻抗大小,浮点型,以一个空格分开。输出并联之后的阻抗大小,结果保留小数点后2位。
我写的代码:
// The Wrong Answer #1
#include <bits/stdc++.h>
using namespace std;
int main() {
double r, r1, r2;
scanf("%lf%lf", &r1, &r2);
r = (double) 1 / (1 / r1 + 1 / r2);
printf("%.2lf", r);
return 0;
}

代码是没有任何问题的,但是注意看:

这就很令人破防了,把double改成float,再将%lf改成%f后就神奇的AC了。
这还只是其中一个。
题目5
内容:两个整数a和b分别作为分子和分母,既分数 a/b ,求它的浮点数值(双精度浮点数,保留小数点后9位),输入仅一行,包括两个整数a和b(b不为0),输出也仅一行,分数 a/b 的浮点数值(双精度浮点数,保留小数点后9位)
看上去这题很简单,但实际上:

其中,前九次是我把题干读错了,的确我看了示例输入输出我还以为只取小数点后面的数就行了。
第10遍估计写法可能有点错误,第11遍在用printf()函数的时候将后面的变量多带了一个"&"符号,查了半天才查出来,第12遍才AC的。
题目6
内容:甲流并不可怕,在中国,它的死亡率并不是很高。请根据截止2009年12月22日各省报告的甲流确诊数和死亡数,计算甲流在各省的死亡率。输入仅一行,有两个整数,第一个为确诊数,第二个为死亡数。输出也仅一行,甲流死亡率,以百分数形式输出,精确到小数点后3位。
我先给出个错误代码,看看各位能不能看出问题(a是总数,b是死亡人数):
// The Wrong Answer #2
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
double c, d;
scanf("%d%d", &a, &b);
c = (double) a / b;
d = (double) c * 100;
printf("%.3d%%", d);
return 0;
}
相信各位很快的就发现了这个问题:总数跟死亡人数除得出的到底是什么鬼,算出来到时候算个死亡率30000%,结果"如此高的死亡率"为何造就了300000人的总数里死亡人数还比300000人少的,关键不是少的问题,是少得多。
很显然这个所谓的死亡率应该是死亡率的倒数(不×100估计就是),也就是说这个值错的很离谱。
修这个问题很简单,把a/b改成b/a就行了。
但这个小问题我仍然查了将近20分钟,的确,下次写代码的时候一定要注意。
题目17
内容:平面上有一个三角形,它的三个顶点坐标分别为(x1, y1), (x2, y2), (x3, y3),那么请问这个三角形的面积是多少?输入仅一行,包括6个单精度浮点数,分别对应x1, y1, x2, y2, x3, y3。输出也是一行,输出三角形的面积,精确到小数点后两位(提示:海伦公式)
我不知道题目17的出题人是怎么想的,我怀疑这跟那个马里奥那道题一样纯属就是折腾人,亦或者是我还没找到更优的解法:
// The Wrong Answer #3
#include <bits/stdc++.h>
using namespace std;
int main() {
double x1, x2, y1, y2, x3, y3;
double kx1, kx2, kx3, ky1, ky2, ky3;
double kxyp1, kxyp2, kxyp3, xy1, xy2, xy3;
double p, S;
scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3);
kx1 = abs(x1 - x2);
ky1 = abs(y1 - y2);
kxyp1 = kx1 * kx1 + ky1 * ky1;
xy1 = sqrt(kxyp1);
kx2 = abs(x2 - x3);
ky2 = abs(y2 - y3);
kxyp2 = kx2 * kx2 + ky2 * ky2;
xy2 = sqrt(kxyp2);
kx3 = abs(x1 - x3);
ky3 = abs(y1 - y3);
xy3 = sqrt(kxyp3);
p = (xy1 + xy2 + xy3) /2;
S = sqrt(p * (p - kx1) * (p - kx2) * (p - kx3));
printf("%.2lf", S);
return 0;
}
写完这段代码果然是Wrong Answer。

这代码很显然,kxyp3没有算,线段长要用的是xy而非我错误代码处写的kx(这点看变量就能看出来了)
改了两回后终于改对然后AC了:

论这道题有没有实际意义,我觉得其实熟悉一下公式和对C++的手感还是有那么点用的。
当然,如果真的是想练脑子,那肯定没太多作用,本身就是一道比较注重细节的题目,你也不好说什么。
题目14
内容:一只大象口渴了,要喝20升水才能解渴,但现在只有一个深h厘米,底面半径为r厘米的小圆桶(h和r都是整数)。问大象至少要喝多少桶水才会解渴。输入有一行:包行两个整数,以一个空格分开,分别表示小圆桶的深h和底面半径r,单位都是厘米。输出一行,包含一个整数,表示大象至少要喝水的桶数。
虽然这题本质上并不难,是一道典型的小学题,但我疑似把这个问题复杂化了,于是就造成的以下结果:

前面的Wrong Answer估计是4/3害的,C++此处得写4.0/3,不然4/3在C++就相当于整型与整型相除,后面位数舍了只保留前面的1,纠正了这个错误后,我写了段距离正确答案十分相近的答案:
// The Wrong Answer #4
#include <bits/stdc++.h>
using namespace std;
int main() {
int r, h;
double v, num;
const double pi = 3.14159;
scanf("%d%d", &r, &h);
v = (double) pi * r * r * h / 1000.0;
num = 20.0 / v;
cout << ceil(num);
return 0;
}

当我一筹莫展,感觉这都是对的时候,我发现我的输出结果疑似跟例题中的不太一样,我马上反着输入了一遍样例输入,果然就对上了。
看了一眼题目,果然:

没看题,顺序又反了。
调了一下顺序后,果然AC了。
题目19
内容:输入两个正整数A和B,求A*B。
这题十分的简单,但也是个坑货(以下又是我的错误代码):
// The Wrong Answer #5
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
scanf("%d%d", &a, &b);
cout << a * b;
return 0;
}
运行起来这绝对是符合题意的,but:

一看题目才知道:哇,正整数!
那么直接用unsigned int定义不就行了嘛,果然AC了。
题目18
内容:给出一个等差数列的前两项a1,a2,求第n项是多少。
这道题很简单,无脑套公式就行了,但我不知道我为什么要加个绝对值(画蛇添足?):
// The Wrong Answer #6
#include <bits/stdc++.h>
using namespace std;
int main() {
int i, j;
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
i = abs(a - b);
j = a + (c - 1) * i;
cout << j;
return 0;
}
运行结果不出意外,WA。

后面拿a-b也是Wrong Answer,这个公差应该是第二项减去第一项。
把赋给i的值改成b-a后就AC了。
总结
本周刷这一部分的过程比较痛苦,其实主要原因就是平时的习惯不太好,尤其是不爱读题的习惯。
这一次练题,其实也培养了我审题的习惯,同时也让我更有耐心,也在一定程度上改了我"急于求成,不读完题就做题"的一些栏习惯。
不得不说,这一次虽然刷的过程不顺利,但起码也让我思维有了些提升,改了我一些习惯并且逐渐有了一些比较好的习惯。

那么这周就练到这里吧,晚安。
参与讨论