您的位置:首页 > 其它

一个简单的小题目引发的血案

2017-02-25 17:01 246 查看
我们在做题的时候,经常遇到一些情况,就是明明能过样例,但是提交却总是WA,往往会让人内心崩溃,提交一遍两遍还行,如果提交了四遍以上,我就会想,唉,算了吧,先换一题,换换思路,后来又想,都已经做了这么久了,再找一下就能找到结果了,我以我最近一个提交了7次才AC的经验来警示自己,以此自勉:

题目描述:

有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,它们到底是真还是假,也就是这种整数到底存不存在,实在有点吃不准,你能快速回答吗?看来只能通过编程。

例如:

x + y = 9,x * y = 15 ? 找不到这样的整数x和y

1+4=5,1*4=4,所以,加起来等于5,乘起来等于4的二个整数为1和4

7+(-8)=-1,7*(-8)=-56,所以,加起来等于-1,乘起来等于-56的二个整数为7和-8

Input

输入数据为成对出现的整数n,m(-10000

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,m,p,delta;
scanf("%d%d",&n,&m);
while(n!=0||m!=0){
float x;
delta=n*n-4*m;
if(delta<0)printf("No\n");
else{
x=(n+sqrt(delta))/2;
p=(int)x;
if(fabs(x-p)<1e-6) printf("Yes\n");
//因为当时经验不足,如果这里用  int p ;p=sqrt(delta); 判断下面这个(x*x==delta )条件更好
else printf("No\n");
}
scanf("%d%d",&n,&m);
}
return 0;
}


再看看第一次的题解

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,m,p;
scanf("%d%d",&n,&m);
float delta,x;
delta=n*n-4*m;
x=(n+sqrt(delta))/2;
p=(int)x;
if(x-p<1e-6) printf("YES");
else printf("NO");
return 0;
}


出错的原因是,Yes-变成了YES, 而我再修改程序的时候一直没有发现这个问题,所以这是修改很多次的主要原因。

又因为这个程序的问题其实特别多,首先没有判断delta是否大于零,没有循环,并且没有考虑x-p是负数的情况

并且当我发现没有判断delta的时候

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,m,p;
scanf("%d%d",&n,&m);
while(n!=0||m!=0){
float delta,x;
delta=n*n-4*m;
if(delta<0)printf("No\n");
else{
x=(n+sqrt(delta))/2;
p=(int)x;
if(x-p<1e-6) printf("Yes\n");
else printf("No\n");
scanf("%d%d",&n,&m);
}
}
return 0;
}


因为第二个scanf的读入放在了else的括号里面

这样就导致了输出很多个NO,就变成了可怜的Output Limit Exceeded

自以为还很对……

事实上,比较好的方法是直接把SCANF放在while的条件里面,还能省掉一
4000
个语句,节省时间。

错了那么多次,一个简单的程序,也是一个深刻的教训,写程序的时候,首先要对一些编程养成良好的习惯,比如怎么写循环中的输入条件,和判断是不是整数的方法,这样可以规避一些问题,同时要考虑问题全面,这样才能够避免一些各种各样的WA……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  小错误的规避