NYOJ 96 n-1位数

本文探讨了在编程竞赛中遇到的精度问题,特别是在使用pow函数时的常见陷阱。通过对比两种解决方案,一种是调整pow函数的计算结果,另一种是采用巧妙的输入处理技巧,文章详细解释了如何避免精度损失,确保输出正确。此外,还分享了一个简洁高效的代码示例,展示了如何跳过输入的第一个数字,从而绕过精度问题并简化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

n-1位数

时间限制:3000 ms  |  内存限制:65535 KB

难度:1

描述

已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。

输入

第一行为M,表示测试数据组数。
接下来M行,每行包含一个测试数据。

输出

输出M行,每行为对应行的n-1位数(忽略前缀0)。如果除了最高位外,其余位都为0,则输出0。

样例输入

4
1023
5923
923
1000

样例输出

23
923
23
0

我知道这个题很简单,但是里面的东西还是挺多的,如果你的代码是AC的请你再测试一下以下样例:

样例输入

233

670

777

890

样例输出:

35

76

84

98

如果你没有出现这样的情况那你的代码就合格了。不巧的是我在测试这些样例的时候就出现了这种情况。这是为什么呢???????百思不得其解!!!但是我坚信这个问题一定出在pow上面。下面先让大家看一下我的ac代码(有问题的代码)

#include<cstdio>
#include<math.h>
int main()
{
    int n,m,i,y;
    scanf("%d",&n);
    while(n--)
    {
        i=0;
        scanf("%d",&m);
        int x=m;
        while(x!=0)
        {
            x/=10;
            i++;
        }
        y=pow(10,i-1);
        printf("%d\n",m%y);
    }
     return 0;
}

于是我就去百度关于pow这个东西的精度问题。看了一圈没说实话没大明白(估计是我有点笨)。不过我还是可以把解决办法教给大家的。pow(a,b);//其作用是计算a的b次方。a,b及函数值都是double型。 如果你想让y直接定义成double的话 是不可以的 因为下面的取余操作是整数与整数之间的。那么怎么才能解决这个精度问题呢?(1)改成 y=pow(10,i-1)+0.1(这里加0.1,0.01,精度较高的都可以);(2)进行简单的+1处理,改成 y=pow(10,i-1)+1;(改成其他数是不可以的,至少我试了一堆数都不可以)个人建议第一种方法比较好。

好了说完这个问题我带大家看看大神是怎么写这道题的!


#include<cstdio>
int main()
{
    int n,m;
    scanf("%d",&n);
    while(n--)
    {
        scanf(" %*c%d",&m);
        printf("%d\n",m);
    }
     return 0;
}

看完我也是无语了~~~

scanf 格式中,如果在%后面、格式字符前面加上一个“*”附加说明符,表示跳过该输入,输入的数据不放入变量中。

例如:

scanf("%*c")是读一个字符但不存储。
scanf("%*1d")则是读一个“十进制数字字符”但不存储。

 这里的scanf(" %*c%d",&m);(%*c前面的空格是为了跳过回车)很巧妙地跳过了第一个数字,将剩余的当做一个整数存储。既解决了前导零又避免了精度的问题。不得不说佩服!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值