问题:
函数 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