末位零问题(换种思路,问题能被无限倍的简化,这就是算法的魅力!)

问题:

函数  f(x)

表示   x 末位零的个数,例如 f(1200)=2 f(1234)=0

现在已知   n   ,k。n<2^31  k<9

求 min(z)  f(z)=k   且z%n=0。


输入:

多组输入,每组两个整数

输出:

每组输出一个答案占一行。


刚开始是这样想的

#include <stdio.h>
int pow1(int a,int  b) //定义快速幂函数
{
    int t=1,m=a;
    while(b!=0)
    {
        if(b&1==1) t*=m;
        m*=m;
        b>>=1;
    }
    return t;
}
int main()
{
        int n,k,a,b;     
        int i;
        while(scanf("%d %d",&n,&k)!=EOF)  // k表示一个数末尾 0 的个数, n是这个数的约数
                                          //  求出这个数的最小值。。

        {
            i= 2;
            a=pow1(10,k);   // 首先满足末尾有k个0 的最小值  肯定是10的k次方
            b=a;
            while(i != 0)
            {
            if(b%n == 0)   //判断这个数是不是n的倍数
            {
                printf("%d\n",b);  //如果是  就输出这个数
                break;
            }
            else                // 如果不是
            {
                b=a*i;         //  就依次把这个数乘2、3、4、5……一直到是n的倍数为止
                i++;
            }
            }

        }                         
    return 0;
}
  这样写答案一定是对的, 但是如果k=0,n=2^30  就要循环2^30次方次!!!显然要超时!!!的!!!

下是一种很巧妙的方法!

灵活的运用打表,gcd,!

仔细想下题的意思,要求的z就是 n 和 10^k的最小公倍数吧!!!

能想到这里就简单了!!!


typedef long long LL;    

LL gcd(LL a, LL b)                         //定义gcd函数
{
    return b!=0 ? gcd(b, a % b) : a;
}
int main()
{
    int i;
    LL n, k, res[10];
    res[0] = 1;
    for(i = 1; i < 10; ++i)             
    {
        res[i] = res[i - 1] * 10;      //数组赋值 10^0--10^9,因为k最大是9哈!
    }
    while(scanf("%lld %lld", &n, &k) != EOF)
    {
        printf("%lld\n", n * res[k] / gcd(n, res[k]));//   求最小公倍数  ,也就是z
    }
    return 0;                                      // 不论k的值是多少,直接出答案!!
}

换种思路,问题能被无限倍的简化,这就是算法的魅力!

n,k

n<231,k<9

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值