UVA 10061 - How many zero‘s and how many digits ?

题目大意:输入n,m。求n!在m进制中末尾有几个零,以及为几位数。

解题思路:林炜大佬打得代码。。。漂亮。n!在m进制有几位,卡精度,用斯特林公式wa了。用对数求,加上1e-9才过。对数求法是这样的。。。设结果为X位数,那么n!< m^X。所以X = logm(n!) = logm (2) + ...logm(n)。而末尾0的求法,是求出m的质因数,然后算2~n,能被不同的m质因数整除的为质因数的几倍,取最少的,则为末尾的0。例如:5 16。16 = 2 * 2 * 2 * 2。2~5只有2、4可以被2整除,一共3个2。要求4个2才能一个0。所以末尾没有0。

ac代码:

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int n, k, cnt, num, m;
int vis[2000005], mark[2000005];
double zero;
int main()
{
	while (scanf("%d%d", &n, &k)!=EOF){
		memset(vis, 0, sizeof(vis));
		memset(mark, 0, sizeof(mark));
		zero = 0; 
		if ( !n || n == 1)
			zero = 1;
		else{
			for (int i = 2; i <= n; i++)
				zero += log(i);
			zero  = floor( zero/log(k) + 1e-9 ) + 1; 
		}		
		m = k;	
		for(int i = 2; i <= k; i++)
			while(k%i==0){
				vis[i]++;
				k /= i;
			}
		for(int i = 2; i <= n; i++){
			int d =sqrt(i);
			int s = i;
			for(int j = 2; j <= d; j++)
				while(s % j==0){
					mark[j]++;
					s/=j;
				}
			mark[s]++;
		}
		int cnt = 99999999;
		for(int i = 1; i <= m; i++)
			if(vis[i])
				cnt = min(mark[i]/vis[i],cnt);
		printf("%d %.0lf\n", cnt, zero);
	}
return 0;
}

大佬手打质数表,存一份:

for(int i = 2; i <= 800; i++)
	if(!p[i]){
		p[++p[0]] = i;
		for(int j = 2*i; j <= 800; j+=i)
			p[j] = 1;	
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值