Codeforces 1114C

Codeforces 1114C

  • 题目
    1114C

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

  • 分析
    首先要知道对于十进制下 n ! n! 有多少个末尾 0 0 10 10 能质因数分解为 10 = 2 5 10 = 2 * 5 ,那么末尾为 0 0 就是看 1 n 1{\sim}n 分解后有多少个 2 5 2和5 ,又因为 2 2 的个数大于 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}} .
    通过以下函数计算

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

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

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

#include<bits/stdc++.h>
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<<minn<<endl;
}
int main ()
{
    cin>>a>>b;
    solve();
	return 0 ;
}
  • 方法
    质因数分解,题目分析
  • 总结

猜你喜欢

转载自blog.csdn.net/strategist_614/article/details/86993158