牛客小白月赛23 阶乘 (二分查找)

链接:https://ac.nowcoder.com/acm/contest/4784/B

题目描述

给定一个正整数 {p}p
求一个最小的正整数 {n}n,使得 {n!}n! 是 {p}p 的倍数

输入描述:

第一行输入一个正整数{T}T表示测试数据组数
接下来T行,每行一个正整数p

输出描述:

输出{T}T行,对于每组测试数据输出满足条件的最小的n

输入

4
1
2
4
8

输出

1
2
4
4

思路:

我们可以p分解成若干个质数相乘,n!也分解成若干个质数相乘,只要n!分解的质数>=p分解的质数,此时的n就满足条件。可以用二分查找的方式去找到最小满足条件的n。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int num[maxn],primer[maxn],cnt=0;
inline void solve(int p)
{
    
    
	cnt=0;
	for(int i=2;i*i<=p;i++)
	{
    
    
		if(p%i==0)
		{
    
    
			primer[++cnt]=i;//记录p的因子 
			while(p%i==0)
			{
    
    
				num[cnt]++;//p因子的数量 
				p/=i;
			}
		}
	}
	if(p>1)//剩下的数 
	{
    
    
		primer[++cnt]=p;
		num[cnt]++;
	}
 } 
 inline bool check(int mid)
 {
    
    
 	for(int i=1;i<=cnt;i++)
 	{
    
    
 		int sum=0,x=mid;
 		while(x)
 		{
    
    
 			sum+=x/primer[i];
 			x/=primer[i];
		 }
		 if(sum<num[i])//n的因子是否大于等于p的因子 
		 return false;
	 }
	 return true;
 }
int main()
{
    
    
	int p,t;
	cin>>t;
	while(t--)
	{
    
    
		cin>>p;
		int l=1,r=1e9,ans,mid;
		memset(num,0,sizeof(num));
		memset(primer,0,sizeof(primer));
		solve(p);
		while(l<=r)
		{
    
    
			mid=(l+r)>>1;
			if(check(mid))
			r=mid-1;
			else
			l=mid+1;
		}
		cout<<l<<endl;
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/xiaolan7777777/article/details/105503538