Problem
链接:https://ac.nowcoder.com/acm/problem/21674
来源:牛客网
牛牛最近在学习初等数论,他的数学老师给他出了一道题,他觉得太简单了, 懒得做,于是交给了你,
题目是这样的:
有一堆数,问你能否从中选出若干个数使得这些数的最小公倍数为x
输入描述:
第一行输入一个整数n (1 ≤ n ≤ 50)
第二行输入n个整数ai (1 ≤ ai ≤ 109)
第三行输入一个整数x (2 ≤ x ≤ 109)
输出描述:
如果可以,输出"Possible"
否则输出"Impossible"
输入1
4
2 3 4 5
20
输出1
Possible
输入2
3
2 3 4
611
输出2
Impossible
输入3
3
2 3 4
12
输出3
Possible
输入4
10
1 2 3 4 5 6 7 8 9 10
24
输出4
Possible
备注:
子任务1:x <= 1000
子任务2:x <= 1000000
子任务3:无限制
Solve
既然要找最小公倍数x,那么a[i]必须是x的因子。
这些x的因子a[i]的最小公倍数lcm如果能够被x整除,那么这个x就一定能被取到。
为什么呢?
比如\(x=p_1^{\alpha_1}p_2^{\alpha_2}\cdots p_s^{\alpha_s}\)
那么\(a[i]=p_1^{\beta_1}p_2^{\beta_2}\cdots p_s^{\beta_s},\,\,\beta_i<\alpha_i\)
如果lcm正好是x的倍数,那么一定可以对于每一个素数,lcm的指数一定不小于x的指数,而每一个a[i]的指数都小于x的指数。
公倍数是所有指标里面取最大值,因此这个lcm最大就是x!
因此lcm==x就有解!
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int a[100];
int main()
{
int n,x;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
scanf("%d",&x);
ll lcm=1;
for(int i=0;i<n;i++){
if(x%a[i]==0){
lcm=(ll)a[i]*lcm/gcd(a[i],lcm);
}
}
if(lcm==x){
cout<<"Possible"<<endl;
}else{
cout<<"Impossible"<<endl;
}
return 0;
}