阶乘
题目描述:
给定一个正整数 p
求一个最小的正整数 n,使得 n! 是 p 的倍数
输入描述:
第一行输入一个正整数T表示测试数据组数
接下来T行,每行一个正整数p
输出描述:
输出T行,对于每组测试数据输出满足条件的最小的n
样例输入:
4
1
2
4
8
样例输出:
1
2
4
4
备注:
(Tleq10^3,pleq10^9)
思路:
-
直接查找一个阶乘可以摸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; }
-
将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; }