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
空间和时间是有联系的嘛!
还有一种二叉堆的做法、 判重比较方便 不多说
如有神牛直接用堆(不是二叉堆)过了 恳请指点
这里介绍堆解法
即
每一趟,堆顶为第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.
相关文章推荐
- USACO Section 3.1 Humble Numbers - 在朴素的算法中找到优化~我吐了...
- usaco 3.1 humble
- 【USACO 3.1】Humble Numbers(给定质因子组成的第n大的数)
- USACO 3.1 Humble Numbers丑数_优先队列
- usaco-3.1-Humble Numbers-<set的使用>
- USACO 3.1 Humble Numbers丑数
- USACO-Section 3.1-PROB Humble Numbers
- USACO3.1Humble Numbers[...]
- usaco 3.1 Humble Numbers
- USACO section3.1 Humble Numbers题解&代码
- USACO Section 3.1 Humble Numbers
- USACO 3.1 Humble Numbers (humble)
- USACO 3.1 humble numbers
- USACO 3.1 Humble Numbers
- USACO 3.1 Humble Numbers
- usaco-3.1-humble-pass
- USACOTrainning.Section 3.1.Humble Numbers
- USACO 3.1 Humble Numbers
- USACO 3.1 Humble Numbers丑数
- usaco 3.1 Humble Numbers