7-19 支票面额 (15 分)

一个采购员去银行兑换一张y元f分的支票,结果出纳员错给了f元y分。采购员用去了n分之后才发觉有错,于是清点了余额尚有2y元2f分,问该支票面额是多少?

输入格式:

输入在一行中给出小于100的正整数n。

输出格式:

在一行中按格式y.f输出该支票的原始面额。如果无解,则输出No Solution

 

输入样例1:

23

输出样例1:

25.51

输入样例2:

22

输出样例2:

No Solution

解析:这道题 乍一看十分“弱智”,却隐藏着一个“深不见底”的大坑,我被卡了一晚上(别笑,maybe我确实菜鸡,卡在第一个测试点上,怎么也想不通)后来只好去百度了别人的代码,忽然有一种茅厕顿开的感觉....

首先,按照正常逻辑思维来说,我们会讨论两种情况:

1.y>n  这就意味着,我们可以推出一组方程(两个等式):

f==2y;

y-n==2f;

但是,很显然,我们可以得到这个方程是负数解,钱不可能是负的,所以(按照正常想法),我们自然可以得出一个结论:y要比n小,也就是第二种情况是必然成立的。

 

2.y<n  这也意味着,我们可以推出一组方程(两个等式):

f-1==2y;

100+y-n==2f;

按照正常想法,我们自然可以解出方程:y=(98-n)/3;f=2*y+1;

所以我会这样写:scanf一个n之后,if((98-n)%3!=0),那我们就可以直接判断 No solution了,因为钱的单位不管是元还是分,都不可能是小数,必然是整数。然而,然而...

第一个测试点就是不对。

所以,到底错在哪里呢?

这就要回到我们第二种情况最开始的那两个方程,当我们用掉n分之后,所剩下的2y元和2f分真的和最初的钱数有那样的一一对应的关系吗?

并不是,仔细想想平常生活中用现金买东西,我们会发现最后手里剩下的零钱是一大把的,也就是说,在银行给我们钱之后,我们没有花钱之前,我们可以保证,y分的范围一定是小于100的,但是当我们花掉n分钱后,因为在这期间有可能会产生找零的各种情况,我们最后所剩下的2f分钱有可能就是大于100的,举个栗子:n==97,最开始我们有68元,33分,花掉97分之后,我们剩下66元,136分(我们可以统一到分为单位 验证一下),那么在这种情况里,我们就不能简单地写做:f-1==2y;100+y-n==2f;

不然这会导致看似 No solution,其实是有解的情况。

我猜,这就是第一个测试点卡我的原因。

写代码时候,我们可以直接用两个for循环完事儿,就不用再管(98-n)%3是否为0,但是我觉得代码按照一定逻辑来写也是可以的,虽然看起来冗余了一些。先验证(98-n)%3是否为0,如果为0,直接算出来y和f;如果不为0,再用两个for循环去寻找我们的y和f,也就是暴力搜索。如果这都找不到,那就是 No solution了。


#include<cstdio>
#include<iostream>
using namespace std;

int y,f,n;

int main(){
scanf("%d",&n);
y=(98-n)/3;
f=2*y+1;

if((98-n)%3==0) printf("%d.%d\n",y,f);      
else{
    for(int i=0;i<100;i++){
        for(int j=0;j<100;j++){
            if((2*i*100+2*j)==(j*100+i-n)){
                printf("%d.%d\n",i,j);
                return 0;
            }
        }
    }
    printf("No Solution\n");
}

return 0;
}

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值