原题链接
题目描述
panda是个数学怪人,他非常喜欢研究跟别人相反的事情。最近他正在研究筛法,众所周知,对一个范围内的整数,经过筛法处理以后,剩下的全部都是质数,不过panda对这些不感兴趣,他只对被筛掉的数感兴趣,他觉得在这些被筛掉的数中一定隐藏着重要的宇宙秘密,只是人们还没有发现罢了。
panda还觉得如果只是单纯地从小到大筛的话,还不足够发现其中的奥秘,于是他决定对至多只包含某些质因数的数进行研究(比如说至多只包含质因数2,3的数有2,3,4,6,8,9,……),他需要得到这些数中第k小的数(k是panda认为的宇宙系数),请你编个程序,帮助他找到这个数。
输入输出格式
输入格式:
第1行有2个数n,k,n代表质因数的个数,k代表那个宇宙系数(1<=n<=100,1<=k<=100000)
第2行有n个数,代表这n个质因数。(每个均小于1000,且不相同)
输出格式:
仅1行,即至多只包含这n个质因数的数中第k小的数。(这个数不会超过2000000000)
输入输出样例
输入样例#1:
2 7
3 5
输出样例#1:
45
对于这道题,我们首先能够想到的是用优先队列,这样能够使在队列中快速地找到第k小的数,但是这样打处理不好就会有一个点MLE。所以我们可以使用数组来模拟队列,注意到虽然k比较大,但是n还是比较小的。我们用b[i]记录a[i]在ans数组的位置,每找到一个新的数就进行判重,一共进行k遍,时间复杂度即为O(nk)。
#include<cstdio>
#include<algorithm>
using namespace std;
int n,k,a[105],b[105],ans[100050],i,cnt=0,min_,min_x;
int main()
{
scanf("%d%d",&n,&k); ans[0]=1;
for (i=1;i<=n;i++) scanf("%d",&a[i]);
while (cnt<k)
{
min_=2147483647;
for (i=1;i<=n;i++) if (ans[b[i]]*a[i]<min_)
{
min_=ans[b[i]]*a[i]; min_x=i;
}
b[min_x]++;
if (min_!=ans[cnt]) ans[++cnt]=min_;
}
printf("%d",ans[k]);
return 0;
}