[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++

猜你喜欢

转载自www.cnblogs.com/wzc521/p/11736719.html