牛客小白月赛23 B-阶乘

阶乘

题目描述:

给定一个正整数 p

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

输入描述:

第一行输入一个正整数T表示测试数据组数

接下来T行,每行一个正整数p

输出描述:

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

样例输入:

4
1
2
4
8

样例输出:

1
2
4
4

备注:

\(T\leq10^3,p\leq10^9\)

思路:

  1. 直接查找一个阶乘可以摸p,但是如果直接搜索一定会TLE,所以搜索过程中,我们要进行判断,如果p可以由当前值和一个不相等的素数相乘得到,那么就可以将这个素数看作可能结果,最后将所有可能结果取最大即可。

    /************************************************
    * @Author: leaflove
    * @Date:   2020-03-23 08:00:09
    * @File:   阶乘.cpp
    * @Remark:   
    ************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) (x&(-x))
    #define INF 0x3f3f3f3f
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn = 111111;
    
    bool isprime(ll p){
    	for(int i=2;i*i<=p;i++)
    		if(p%i==0) return false;
    	return true;
    }
    
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	FAST;
    	int t;
    	cin>>t;
    	while(t--){
    		ll p,ans=0;
    		cin>>p;
    		ll n=1;
    		for(int i=1;;i++){
    			n*=i;
    			if(n%p==0){
    				ans=i;
    				break;
    			}
    			if(p%i==0&&p/i!=i){
    				if(isprime(p/i)){
    					ans=max(1ll*i,p/i);
    					break;
    				}
    			}
    			n%=p;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  2. 将p质因数分解,并记录每个因子的个数,然后对于每个因子二分搜索最小的包含该因子数量大于等于p中包含数量的阶乘,将这些二分结果取最大。

    /************************************************
    * @Author: leaflove
    * @Date:   2020-03-23 08:18:23
    * @File:   阶乘2.cpp
    * @Remark:   
    ************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) (x&(-x))
    #define INF 0x3f3f3f3f
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn = 111111;
    int cnt[maxn];
    
    int getnum(int x,int y){
    	int ans=0;
    	while(x){
    		ans+=x/y;
    		x/=y;
    	}
    	return ans;
    }
    
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	FAST;
    	int t;
    	cin>>t;
    	while(t--){
    		CSE(cnt,0);
    		ll p;
    		cin>>p;
    		ll n=p;
    		for(int i=2;i*i<=p;i++){
    			while(p%i==0){
    				cnt[i]++;
    				p/=i;
    			}
    		}
    		int ans=p;
    		for(int i=2;i*i<=n;i++){
    			if(n%i==0&&cnt[i]){
    				int l=0,r=1e9,q;
    				while(l+1<r){
    					int mid=l+r>>1;
    					if(getnum(mid,i)>=cnt[i]){
    						r=mid,q=mid;
    					}
    					else
    						l=mid;
    				}
    				ans=max(ans,q);
    			}
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
posted @ 2020-03-23 09:22  落水清心  阅读(288)  评论(0编辑  收藏  举报