UVa OJ 568

1、刚开始以为和普通的取余一样,每次乘了n后再去掉后面的零,结果不对。举出反例:25*6,若先取5*6,结果是3,但实际上,最后一位应该是5。

2、产生这种情况的原因是题目要求去掉末尾的一串零。实际上,中间过程去掉0的时候,产生的“末位”3并不是真正的非零末位,而是要加到倒数第二位(与2*6=12的2相加)后才是非零末位——想象一下,如果不去掉0的话,那么实际上3还要进到前一位,因为它不是末位数(列竖式的时候,只有最末尾不受中间过程加减法的制约)。所以,只留尾数相乘再%10与直接相乘再%10相等的这种情况,只有对末尾数字才能成立,对于对中间结果去掉尾0这种情况,实际上得到的“最后一位”是原来数的中间一个数,因此要受各种条件的制约(与别的数做加法、减法)。综上,这种数论算法行不通。

3、产生0的原因实际上就是2和5,所以,统计2和5因子的个数,先统一去掉2和5,这样不会产生0,保证最后一位是“真正的最后一位”,然后再乘回去即可。程序如下:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int count=0,n,num2=0,num5=0,temp,f=1,i;
    while(scanf("%d",&n)==1)
    {
        num2=0;num5=0;f=1;
           for(i=n;i>=1;i--)
           {
               temp=i;
               while(temp%2==0)
               {
                    num2++;
                    temp/=2;
               }
               while(temp%5==0)
               {
                   num5++;
                   temp/=5;
               }
               f*=temp;
               f%=10;
           }
           if(num2>num5)
               while(num2>num5)
               {
                   f*=2;
                   num2--;
                   f%=10;
               }
           if(num2<num5)
               while(num2<num5)
               {
                   f*=5;
                   num5--;
                   f%=10;
               }
            printf("%5d -> %d\n",n,f);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值