Codeforces 1114C

Codeforces 1114C

  • 题目
    1114C

  • 题意
    b b b进制下的 n ! n! n!末尾有多少 0 0 0

  • 分析
    首先要知道对于十进制下 n ! n! n!有多少个末尾 0 0 0 10 10 10能质因数分解为 10 = 2 ∗ 5 10 = 2 * 5 10=25,那么末尾为 0 0 0就是看 1 ∼ n 1{\sim}n 1n分解后有多少个 2 和 5 2和5 25,又因为 2 2 2的个数大于 5 5 5的个数,所以最终的答案看的是 5 5 5的个数,计算5的贡献答案即为 n 5 + n 5 2 + n 5 2 … n 5 k {\frac{n}{5}}+{\frac{n}{5^2}}+{\frac{n}{5^2}}{\dots}{\frac{n}{5^k}} 5n+52n+52n5kn.
    通过以下函数计算

    void f(int x,int y)
    {
      if(x < y) return 0;
      else return x/y+(x/y,y);
    }
    

    现在考虑 b b b进制下的情况

    • 分解 b b b的质因数 ∏ i = 1 m p i c i {\prod_{i=1}^m{p_i^{c_i}}} i=1mpici
    • 计算答案并除以 c i c_i ci,再取 m i n min min
      A s As As:为什么答案不直接计算分解出的最大质因数,这样不就求出最少的个数了吗?
      A n An An:这里要考虑到 c i c_i ci的影响。
      A s As As:为什么求 m i n min min的时候要除以 c i c_i ci
      A n An An:因为假设 b b b 40 40 40,那么分解质因数是 2 3 ∗ 5 2^3*5 235,计算时计算了 2 1 , 2 2 , 2 3 2^1,2^2,2^3 21,22,23的贡献,而实际上答案只要 2 3 2^3 23这个数的贡献。因为只有 2 3 和 5 2^3和5 235才能相乘在 b b b进制下等于 0 0 0
  • 代码

#include
using namespace std;
typedef long long ll;
const int N = 1600;
ll a,b;
ll c[N],m = 0,p[N];
void fj()
{
	for(int i= 2;i<=sqrt(b);i++)
	{
		if(b % i== 0)
		{
           p[++m] = i,c[m] = 0;
           while(b %i == 0) b/=i,c[m]++;
		}
	}
	if(b > 1)
		p[++m] = b,c[m] = 1;
}
ll cal(ll x,ll y)
{
	if(x < y) return 0;
	else return x/y+cal(x/y,y);
}
void solve()
{
	ll minn=0x7fffffffffffffff;
	fj();
	for(int i= 1;i<=m;i++)
	{
		minn = min(minn,cal(a,p[i])/c[i]);
	}
	cout<>a>>b;
    solve();
	return 0 ;
}
  • 方法
    质因数分解,题目分析
  • 总结

你可能感兴趣的:(Codeforces 1114C)