您的位置:首页 > 其它

USACO 3.1 humble

2011-02-14 16:21 225 查看
常规解法网上有

这里介绍堆解法



每一趟,堆顶为第i小的丑数,弹出(用堆末和堆顶交换、 不多说)

第i小的丑数分别乘以各个质数,判重后加入堆中 维护(上滑)

主要介绍判重:这里很明显要哈希,而且要拉链 因为丑数可能非常大 比如超过10^7 会MLE的

堆的维护不解释、、

比如4个质数 2 3 5 7 求第19小丑数

1为堆顶,1弹出堆,乘以2 3 5 7分别加入堆

然后2为堆顶,弹出堆,乘以2 3 5 7

然后是3、4……

悲剧的是USACO 内存限制16MB 太抠了 test12 即最后一个点 MLE

如果把数组开大就TLE

空间和时间是有联系的嘛!

还有一种二叉堆的做法、 判重比较方便 不多说

如有神牛直接用堆(不是二叉堆)过了 恳请指点

{
ID: xiaweiy1
PROG: humble
LANG: PASCAL
}
const maxn=1000000;
maxm=999985;
maxx=1000000;
var p:array[0..100]of longint;
k,n,i,done,tot,num,t,res,total,ttt:longint;
heap:array[1..maxn]of longint;
hash:array[1..maxm]of longint;
lian:array[1..maxx,1..2]of longint;
procedure sort(l,r: longint);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=p[(l+r) div 2];
repeat
while p[i]<x do
inc(i);
while x<p[j] do
dec(j);
if not(i>j) then
begin
y:=p[i];
p[i]:=p[j];
p[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function find(x:longint):boolean;
var mo,now:longint;
begin
mo:=x mod 999983;
if hash[mo]=0 then
begin
inc(total);
lian[total,1]:=x div 999983;
hash[mo]:=total;
exit(true);
end
else begin
now:=hash[mo];
if int64(lian[now,1])*int64(999983)+mo=int64(x) then
exit(false);
while lian[now,2]<>0 do
begin
now:=lian[now,2];
if int64(lian[now,1])*int64(999983)+mo=int64(x) then
exit(false);
end;
inc(total);
if total>1200000 then
ttt:=1;
lian[now,2]:=total;
lian[total,1]:=x div 999983;
exit(true);
end;
end;
procedure extract;
begin
heap[1]:=heap[tot]; heap[tot]:=0;
dec(tot);
end;
procedure down(x:longint);
var t1,t2,pnum,tmp,q:longint;
begin
q:=x;
while (q*2<=tot)do
begin
t1:=heap[q*2];
if q*2+1<=tot then t2:=heap[q*2+1] else t2:=maxlongint;
if t1<t2 then pnum:=0 else pnum:=1;
if heap[q]>heap[q*2+pnum] then
begin
tmp:=heap[q]; heap[q]:=heap[q*2+pnum]; heap[q*2+pnum]:=tmp;
q:=q*2+pnum;
end
else
break;
end;
end;
procedure up(x:longint);
var q,tmp:longint;
begin
q:=x;
while x div 2>=1 do
begin
if heap[q]<heap[q div 2] then
begin
tmp:=heap[q]; heap[q]:=heap[q div 2]; heap[q div 2]:=tmp;
q:=q div 2;
end
else
break;
end;
end;
begin
assign(input,'humble.in');
reset(input);
assign(output,'humble.out');
rewrite(output);
readln(k,n);
for i:=1 to k do read(p[i]); //prime;
sort(1,k);
tot:=1; heap[1]:=1;
done:=-1;
while (tot>0)and(done<n) do
begin
num:=heap[1];
res:=num;
inc(done);
extract;
down(1);
for i:=1 to k do
begin
if int64(num)*int64(p[i])>int64(maxlongint) then
break;
t:=num*p[i];
if find(t) then
begin
inc(tot);
heap[tot]:=t;
up(tot);
end;
end;
ttt:=0;

end;
writeln(res);
//while true do ttt:=0;
close(input);
close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: