有N(2<=N<=15)个数A1,A2,….,An-1,An,如果在这N个数中,有且仅有一个数能整除m,那么整数m就是一个幸运数,你的任务就是在给定A1,A2,….,An-1,An的情况下,求出第k小的幸运数。
第一行为一整数数N,K(2<=N<=15,1<=K<=2^31-1),意义如上述。
接下来一行有N个整数,A1,A2,….,An-1,An,这N个整数均不超过2^31-1。
输出一行,仅包含一个整数ans,表示第K小的幸运数。答案保证不超过10^15。
输入1:
2 4
2 3
输入2:
2 100
125 32767
输出1:
8
输出2:
12500
对于50%的数据,N<=5,ANS<=100000
对于80%的数据,N<=10,ANS<=10^15
对于100%的数据,N<=15,ANS<=10^15
观察数据范围:
对于50%的数据是很简单的,只需要暴力。
而要通过后面的数据就有点小困难。
很容易想到最后的答案肯定是A[]中间的某个数乘上一个整数。
看到K怎么大枚举每一个数很显然是不现实的。
我们考虑一下,可不可以把问题转换一下,
看一下可不可以变成一个判断问题。
现在问题就变成了求在区间[1..mid]有多少个符合条件的数。
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
ll a[20],l,r,ans,k,mid;
int n,m;
ll gcd(ll x,ll y)
{
if(x%y==0)return y;else return gcd(y,x%y);
}
void bfs(int x,ll sum,int deep)
{
if(sum>mid)return;
if(deep%2)ans+=floor(mid/sum)*deep;else ans-=floor(mid/sum)*deep;
for(int i=x+1;i<=n;i++)
bfs(i,sum/gcd(sum,a[i])*a[i],deep+1);
}
int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
l=1;
r=1000000000000000;
while(l2;
ans=0;
for(int i=1;i<=n;i++)
bfs(i,a[i],1);
if(ans1;else r=mid;
}
printf("%lld\n",l);
}