牛客算法周周练4 - 阶乘(二分、质因子)
牛客算法周周练4 - 阶乘(二分、质因子)
链接:https://ac.nowcoder.com/acm/contest/5505/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给定一个正整数 p
求一个最小的正整数 n,使得 n! 是 p 的倍数
输入描述:
第一行输入一个正整数T表示测试数据组数
接下来T行,每行一个正整数 p
输出描述:
输出T行,对于每组测试数据输出满足条件的最小的n
示例1
输入
4 1 2 4 8
输出
1 2 4 4
备注:
T≤103,p≤109
题意简洁明了。
我们先把p质因数分解为:p=p1a1*...*pkak
那么我们只需要找到一个数x,使得x!的质因子p1的个数>=a1,p2的个数>=a2……pk的个数>=ak即可,这样就能保证x的阶乘必是p的倍数。
我们所要做的要找到最小的这个x
方法一:
二分x
1 #include <bits/stdc++.h> 2 typedef long long LL; 3 #define pb push_back 4 const int INF = 0x3f3f3f3f; 5 const double eps = 1e-8; 6 const int mod = 1e9+7; 7 const int maxn = 1e5+10; 8 using namespace std; 9 10 struct node 11 { 12 int x;//质因子 13 int num;//次方 14 }fac[maxn]; 15 int cnt=0; 16 17 int judge(int x) 18 { 19 for(int i=1;i<=cnt;i++) 20 { 21 int t=x;//看x!中有多少个fac[i].x 22 int num=0; 23 while(t) 24 { 25 num += t/fac[i].x; 26 t /= fac[i].x; 27 } 28 if(num<fac[i].num) return 0; 29 } 30 return 1; 31 } 32 33 int main() 34 { 35 #ifdef DEBUG 36 freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout); 37 #endif 38 39 int T; 40 scanf("%d",&T); 41 while(T--) 42 { 43 int n; 44 scanf("%d",&n); 45 cnt = 0; 46 for(int i=2;i*i<=n;i++)//质因数分解n 47 { 48 if(n%i==0) 49 { 50 fac[++cnt].x = i; 51 fac[cnt].num = 0; 52 while(n%i==0) 53 { 54 fac[cnt].num++; 55 n/=i; 56 } 57 } 58 } 59 if(n>1) 60 { 61 fac[++cnt].x = n; 62 fac[cnt].num = 1; 63 } 64 int L=1,R=1e9;//二分 65 int ans=n; 66 while(L<=R) 67 { 68 int mid=(L+R)>>1; 69 if(judge(mid)) 70 { 71 R = mid-1; 72 ans = mid; 73 } 74 else L=mid+1; 75 } 76 printf("%d\n",ans); 77 } 78 79 return 0; 80 }
其他解法:
https://blog.nowcoder.net/n/aa5ff9efa80440c897a9aaae4401a467
https://blog.nowcoder.net/n/383b3314be074a11b8ca45f6a75e585c
-