[USACO3.1]丑数 Humble Numbers

来源:互联网 发布:python pyqt5教程 编辑:程序博客网 时间:2024/05/17 19:17

题目背景

对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S。这个正整数集合包括,p1、p1*p2、p1*p1、p1*p2*p3...(还有其它)。该集合被称为S集合的“丑数集合”。注意:我们认为1不是一个丑数。

题目描述

你的工作是对于输入的集合S去寻找“丑数集合”中的第N个“丑数”。所有答案可以用longint(32位整数)存储。

补充:丑数集合中每个数从小到大排列,每个丑数都是素数集合中的数的乘积,第N个“丑数”就是在能由素数集合中的数相乘得来的(包括它本身)第n小的数。

输入输出格式

输入格式:

第 1 行: 二个被空格分开的整数:K 和 N , 1<= K<=100 , 1<= N<=100,000.

第 2 行: K 个被空格分开的整数:集合S的元素

输出格式:

单独的一行,输出对于输入的S的第N个丑数。

输入输出样例

输入样例#1:
4 192 3 5 7
输出样例#1:
27

说明

题目翻译来自NOCOW。

USACO Training Section 3.1



【题解】官方的题解值得借鉴。p(next???失配边???)

/*ID:luojiny1LANG:C++TASK:humble*/#include<cstdio>const int maxk=110,maxn=100100;int K,N,k[maxk],p[maxn]={0},d[maxn]={0}; int main(){freopen("humble.in","r",stdin);freopen("humble.out","w",stdout);scanf("%d%d",&K,&N);for(int i=0;i<K;i++)scanf("%d",&k[i]);d[0]=1;for(int i=1;i<=N;i++){int Min=0x7fffffff;for(int j=0;j<K;j++){while((double)k[j]*d[p[j]]<=d[i-1])p[j]++;//double avoid overflow problems   p[j]表示k[j]与已求丑数相乘 大于前一个丑数 的最小编号 ,在编号p[j]的丑数与k[j]相乘可知总是大于与编号p[j]的丑数相乘 if((double)d[p[j]]*k[j]<Min)Min=d[p[j]]*k[j];  //求得最小值即为下一个丑数 }d[i]=Min;}printf("%d\n",d[N]);return 0;}


原创粉丝点击