1278. 【USACO题库】3.1.3 Humble Numbers丑数

题目描述

对于一给定的素数集合 S = {p1, p2, ..., pK}, 

来考虑那些质因数全部属于S 的数的集合。这个集合包括,p1, p1p2, p1p1, 和 p1p2p3 (还有其它)。这是个对于一个输入的S的丑数集合。

注意:我们不认为1 是一个丑数。

你的工作是对于输入的集合S去寻找集合中的第N个丑数。longint(signed 32-bit)对于程序是足够的。


PROGRAM NAME: humble


INPUT FORMAT














第 1 行: 二个被空间分开的整数:K 和 N , 1<= K<=100 , 1<= N<=100,000.
第 2 行: K 个被空间分开的整数:集合S的元素


SAMPLE INPUT (file humble.in) 

4 19

2 3 5 7


OUTPUT FORMAT

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


SAMPLE OUTPUT (file humble.out)

27



输入

输出

样例输入

 
       

样例输出

 
       

数据范围限制


水水水水水水水水水!
淼淼淼!
一,暴力。33.3分
二,宽搜。但2*5=5*2=10,值会重复出现,很难处理。33.3~100分
三,堆!堆可以维护最小值,依次输出堆顶。对于重复,判断目前堆顶是否
等于上一个堆顶be,等于继续down,直到不等于为止。
而且宽搜第i个状态不一定最小,确定不了宽搜边界,堆没有该问题。
标程(请勿抄袭):
var
        i:longint;
        j,k,m,n,o,p,l,s,t,len,before:int64;
        a,f:array[0..10000000] of int64;
procedure up(x:int64);
begin
        while (x>0) and (a[x]<a[x div 2]) do begin
                t:=a[x];
                a[x]:=a[x div 2];
                a[x div 2]:=t;
                x:=x div 2;
        end;
end;
procedure down(x:int64);
var
        xx,yy:int64;
begin
        while ((x*2<len) and (a[x*2]<a[x])) or ((x*2+1<len) and (a[x*2+1]<a[x])) do begin
                xx:=x*2;
                yy:=x*2+1;
                if a[xx]<a[yy] then begin
                        t:=a[x];
                        a[x]:=a[xx];
                        a[xx]:=t;
                        x:=xx;
                end else begin
                        t:=a[x];
                        a[x]:=a[yy];
                        a[yy]:=t;
                        x:=yy;
                end;
        end;
end;
begin
        
        readln(n,k);
        for i:=1 to n do read(f[i]);
        for i:=1 to n do begin
                a[i]:=f[i];
                up(i);
        end;
        len:=n;
        l:=0;
        before:=0;
        repeat
                inc(l);
                if a[1]=before then begin
                        repeat
                                a[1]:=a[len];
                                down(1);
                                dec(len);
                        until a[1]<>before;
                end;
                before:=a[1];
                for i:=1 to n do begin
                        inc(len);
                        a[len]:=a[1]*f[i];
                        up(len);
                end;
                //writeln(a[1]);
                {for j:=1 to len do begin
                        if a[j]=a[1] then begin
                                a[j]:=a[len];
                                down(j);
                                dec(len);
                        end;
               end;  }
        until l=k;
        writeln(a[1]);
        close(input);close(output);
end.


猜你喜欢

转载自blog.csdn.net/wangyuda123456789/article/details/77200345