[CSP-S模拟测试]:Smooth(数学)
题目传送门(内部题84)
输入格式
两个整数$B,K$
输出格式
一个整数表示答案
样例
样例输入:
5 100
样例输出:
280
数据范围与提示
对于$40\%$的数据,保证答案小于$10^7$
对于另$20\%$的数据,保证答案小于$7\times 10^7$
对于另$20\%$的数据,$B=2$
对于$100\%$的数据,$K\leqslant 10^7,B\leqslant 15$,保证答案小于$10^{18}$
题解
先说一下考场上的做法。
其实挺暴力的,做一个队列,初始只有$1$,每次从枚举质数,将队列里的所有数都乘上它即可。
最后排个序,找第$K$大就好了,期望是$80$分,卡好时间(不要都扫到$10^{18}$,否则会$TLE$)就好了。
再说正解,发现$B$很小,用$B$个指针就好了。
时间复杂度:$\Theta(B\times K)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int B,K,fail[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int pri[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
long long s[10000001];
int main()
{
scanf("%d%d",&B,&K);
s[1]=1;
for(int i=2;i<=K;i++)
{
long long flag=0x3f3f3f3f3f3f3f3f;
for(int j=0;j<B;j++)
{
if(s[fail[j]]*pri[j]==s[i-1])fail[j]++;
if(s[fail[j]]*pri[j]<flag)flag=s[fail[j]]*pri[j];
}
s[i]=flag;
}
printf("%lld",s[K]);
return 0;
}
rp++