时间限制:C/C++ 1秒,其他语言2秒
空间限制: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
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
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://www.cnblogs.com/jiamian/p/12820104.html