海清's profileCockhorse BlogPhotosBlogListsMore ![]() | Help |
|
|
June 09 Section 4.3 The Primes很BT的搜索,完全的手工写了364行,真是辛苦呀,但总算是过了。。。。 TASK: prime3 LANG: PASCAL Compiling... Compile: OK Executing... Test 1: TEST OK [0.024 secs] Test 2: TEST OK [0.024 secs] Test 3: TEST OK [0.032 secs] Test 4: TEST OK [0.06 secs] Test 5: TEST OK [0.056 secs] Test 6: TEST OK [0.1 secs] Test 7: TEST OK [0.116 secs] Test 8: TEST OK [0.148 secs] Test 9: TEST OK [0.168 secs] Test 10: TEST OK [0.24 secs] All tests OK. (本题有很多种搜索顺序,本人的方法还有待改进) 先预处理存下所有合法质数 剪枝:第一行、列可剪去所有含0的质数,末行、末列可剪去所有含偶数数字的质数 搜索顺序:(当然,每一步都要进行可行性剪枝) 这是我的程序(写得很垃圾,不过还是过了) { ID:whqlsc1 LANG:PASCAL TASK:prime3 } const e:array[1..5]of longint=(10000,1000,100,10,1); var a:array[1..5]of longint; p,c:array[1..5,1..5]of longint; h2a,h2b:array[0..9,0..9,0..1000]of longint; h3:array[0..9,0..9,0..9,0..100]of longint; h4:array[0..9,0..9,0..9,0..9,0..10]of longint; b:array[0..10000]of longint; b4:array[0..9,0..9,0..9,0..9,0..10]of longint; d1:array[0..9,0..10000]of longint; d2:array[0..9,1..9,0..1000]of longint; f:array[0..10,0..10,0..10,0..10,0..10]of boolean; ff:array[0..100000]of boolean; g:array[0..100000]of longint; s:array[0..160]of string; ss:string; i,j,k,l,n,m,o,t:longint; function bigger(s1,s2:string):boolean; var i:longint; begin for i:=1 to length(s1) do if (s1[i]<>s2[i]) then begin if s1[i]>s2[i] then exit(true) else exit(false); end; exit(false); end; function find(x:longint):longint; var k,o:longint; begin k:=x;o:=0; while k<>0 do begin inc(o,k mod 10); k:=k div 10; end; exit(o); end; function find0(x:longint):boolean; var k,i:longint; begin k:=x; for i:=1 to 5 do begin if k mod 10=0 then exit(true); k:=k div 10; end; exit(false); end; function find2(x:longint):boolean; var k,i:longint; begin k:=x; for i:=1 to 5 do begin if k mod 10 mod 2=0 then exit(true); k:=k div 10; end; exit(false); end; procedure goa(x:longint); var k,i:longint; begin; k:=x; for i:=1 to 5 do begin a[6-i]:=k mod 10; k:=k div 10; end; end; procedure gof; begin f[a[1],10,10,10,10]:=true; f[10,10,10,10,a[5]]:=true; f[a[1],a[2],10,10,10]:=true; f[a[1],10,a[3],10,10]:=true; f[a[1],10,10,a[4],10]:=true; f[10,a[2],10,10,a[5]]:=true; f[10,10,a[3],10,a[5]]:=true; f[10,10,10,a[4],a[5]]:=true; f[a[1],10,10,10,a[5]]:=true; f[a[1],a[2],10,a[4],10]:=true; f[10,a[2],10,a[4],a[5]]:=true; f[a[1],a[2],10,10,a[5]]:=true; f[a[1],10,a[3],10,a[5]]:=true; f[a[1],a[2],10,a[4],a[5]]:=true; f[a[1],a[2],a[3],10,a[5]]:=true; f[a[1],a[2],a[3],a[4],a[5]]:=true; end; procedure goh(x:longint); var i:longint; begin inc(h2a[a[1],a[5],0]); i:=h2a[a[1],a[5],0]; h2a[a[1],a[5],i]:=x; inc(h2b[a[3],a[5],0]); i:=h2b[a[3],a[5],0]; h2b[a[3],a[5],i]:=x; inc(h3[a[2],a[4],a[5],0]); i:=h3[a[2],a[4],a[5],0]; h3[a[2],a[4],a[5],i]:=x; inc(h4[a[1],a[2],a[4],a[5],0]); i:=h4[a[1],a[2],a[4],a[5],0]; h4[a[1],a[2],a[4],a[5],i]:=x; end; procedure gob(x:longint); var i:longint; begin if x div e[1]=m then begin inc(b[0]); b[b[0]]:=x; end; inc(b4[a[1],a[2],a[4],a[5],0]); i:=b4[a[1],a[2],a[4],a[5],0]; b4[a[1],a[2],a[4],a[5],i]:=x; end; procedure god(x:longint); var i:longint; begin inc(d1[a[1],0]); i:=d1[a[1],0]; d1[a[1],i]:=x; inc(d2[a[1],a[5],0]); i:=d2[a[1],a[5],0]; d2[a[1],a[5],i]:=x; end; procedure search(t:longint); var i,j,k:longint; ss:string; y:boolean; begin if t=1 then for i:=1 to b[0] do begin y:=true; for j:=1 to 5 do if not f[b[i]div e[j] mod 10,10,10,10,10] then begin y:=false;break; end; if not y then continue; for j:=1 to 5 do p[1,j]:=b[i]div e[j] mod 10; search(2); end else if t=2 then for i:=1 to d1[p[1,5],0] do begin y:=true; for j:=2 to 5 do if not f[10,10,10,10,d1[p[1,5],i]div e[j]mod 10] then begin y:=false;break; end; if not y then continue; for j:=2 to 5 do p[j,5]:=d1[p[1,5],i]div e[j]mod 10; search(3); end else if t=3 then begin for i:=1 to h2a[p[1,1],p[5,5],0] do if (f[p[1,2],h2a[p[1,1],p[5,5],i]div e[2]mod 10,10,10,10]) and(f[p[1,3],10,h2a[p[1,1],p[5,5],i]div e[3]mod 10,10,10]) and(f[p[1,4],10,10,h2a[p[1,1],p[5,5],i]div e[4]mod 10,10]) and(f[10,h2a[p[1,1],p[5,5],i]div e[2]mod 10,10,10,p[2,5]]) and(f[10,10,h2a[p[1,1],p[5,5],i]div e[3]mod 10,10,p[3,5]]) and(f[10,10,10,h2a[p[1,1],p[5,5],i]div e[4]mod 10,p[4,5]]) then begin for j:=2 to 4 do p[j,j]:=h2a[p[1,1],p[5,5],i]div e[j]mod 10; search(4); end; end else if t=4 then begin for i:=1 to h2b[p[3,3],p[1,5],0] do if (f[p[1,1],10,10,10,h2b[p[3,3],p[1,5],i]div e[1]mod 10]) and(f[p[1,2],p[2,2],10,h2b[p[3,3],p[1,5],i]div e[2]mod 10,10]) and(f[p[1,4],h2b[p[3,3],p[1,5],i]div e[4]mod 10,10,p[4,4],10]) and(f[10,p[2,2],10,h2b[p[3,3],p[1,5],i]div e[4]mod 10,p[2,5]]) and(f[10,h2b[p[3,3],p[1,5],i]div e[2]mod 10,10,p[4,4],p[4,5]]) and(f[h2b[p[3,3],p[1,5],i]div e[1]mod 10,10,10,10,p[5,5]]) then begin for j:=1 to 2 do p[6-j,j]:=h2b[p[3,3],p[1,5],i]div e[j]mod 10; p[2,4]:=h2b[p[3,3],p[1,5],i]div e[4]mod 10; search(5); end; end else if t=5 then begin for i:=1 to d2[p[5,1],p[5,5],0] do if (f[p[1,2],p[2,2],10,p[4,2],d2[p[5,1],p[5,5],i]div e[2]mod 10]) and(f[p[1,3],10,p[3,3],10,d2[p[5,1],p[5,5],i]div e[3]mod 10]) and(f[p[1,4],p[2,4],10,p[4,4],d2[p[5,1],p[5,5],i]div e[4]mod 10]) then begin for j:=2 to 4 do p[5,j]:=d2[p[5,1],p[5,5],i]div e[j]mod 10; search(6); end; end else if t=6 then begin for i:=1 to h3[p[2,2],p[2,4],p[2,5],0] do if (f[p[1,1],h3[p[2,2],p[2,4],p[2,5],i]div e[1]mod 10,10,10,p[5,1]]) and(f[p[1,3],h3[p[2,2],p[2,4],p[2,5],i]div e[3]mod 10,p[3,3],10,p[5,3]]) then begin p[2,1]:=h3[p[2,2],p[2,4],p[2,5],i]div e[1]mod 10; p[2,3]:=h3[p[2,2],p[2,4],p[2,5],i]div e[3]mod 10; search(7); end; end else if t=7 then begin for i:=1 to h3[p[4,2],p[4,4],p[4,5],0] do if (f[p[1,1],p[2,1],10,h3[p[4,2],p[4,4],p[4,5],i]div e[1]mod 10,p[5,1]]) and(f[p[1,3],p[2,3],p[3,3],h3[p[4,2],p[4,4],p[4,5],i]div e[3]mod 10,p[5,3]]) then begin p[4,1]:=h3[p[4,2],p[4,4],p[4,5],i]div e[1]mod 10; p[4,3]:=h3[p[4,2],p[4,4],p[4,5],i]div e[3]mod 10; search(8); end; end else if t=8 then begin for i:=1 to b4[p[1,1],p[2,1],p[4,1],p[5,1],0] do if f[b4[p[1,1],p[2,1],p[4,1],p[5,1],i]div e[3]mod 10,10,p[3,3],10,p[3,5]] then begin p[3,1]:=b4[p[1,1],p[2,1],p[4,1],p[5,1],i]div e[3]mod 10; search(9); end; end else if t=9 then begin for i:=1 to h4[p[1,2],p[2,2],p[4,2],p[5,2],0] do if f[p[3,1],h4[p[1,2],p[2,2],p[4,2],p[5,2],i]div e[3]mod 10,p[3,3],10,p[3,5]] then begin p[3,2]:=h4[p[1,2],p[2,2],p[4,2],p[5,2],i]div e[3]mod 10; search(10); end; end else if t=10 then begin for i:=1 to h4[p[1,4],p[2,4],p[4,4],p[5,4],0] do if f[p[3,1],p[3,2],p[3,3],h4[p[1,4],p[2,4],p[4,4],p[5,4],i]div e[3]mod 10,p[3,5]] then begin p[3,4]:=h4[p[1,4],p[2,4],p[4,4],p[5,4],i]div e[3]mod 10; search(11); end; end else begin inc(o); ss:=''; for i:=1 to 5 do for j:=1 to 5 do ss:=ss+chr(p[i,j]+48); s[o]:=ss; end; end; begin assign(input,'prime3.in'); assign(output,'prime3.out'); reset(input); rewrite(output); readln(k,m); n:=0;i:=2; while i<100000 do begin if not ff[i] then begin inc(n); g[n]:=i; for j:=1 to 100000 div i do ff[j*i]:=true; end; inc(i); end; l:=0; for i:=1 to n do if g[i]>10000 then begin inc(l); g[l]:=g[i]; end; for i:=1 to l do if find(g[i])=k then begin goa(g[i]); gof; goh(g[i]); if not find0(g[i]) then gob(g[i]); if not find2(g[i]) then god(g[i]); end; o:=0; for i:=1 to 5 do for j:=1 to 5 do p[i,j]:=10; search(1); if o=0 then begin writeln('NONE'); halt; end; for i:=1 to o do for j:=1 to o-1 do if bigger(s[j],s[j+1]) then begin ss:=s[j];s[j]:=s[j+1];s[j+1]:=ss; end; for i:=1 to 25 do begin write(s[1,i]); if i mod 5=0 then writeln; end; for i:=2 to o do begin writeln; for j:=1 to 25 do begin write(s[i,j]); if j mod 5=0 then writeln; end; end; close(input); close(output); end. May 02 Section 3.1Section 3.1.1 Agri-Net 最小生成树 Section 3.1.2 Score Inflation 一道多重背包的题,但转移方法和传统方法有些不同。 用f[i]表示时间为i时,可得到的最大分数; 先初始化,把现有的题目时间所对应的分数赋到f[]上; 枚举时间,f[i]=max{f[i-j]+f[j] (j:=1 to i div 2 do)}; 最后输出f[]中的最大值。 Section 3.1.3 Humble Numbers 一道很科学的题,一下代码可以参考一下。 program humble; var a:array[0..100000] of longint; b,c:array[1..100] of longint; m,n,i,nt:longint; procedure work; var i,r,t:longint; begin r:=1;t:=a[c[1]]*b[1]; for i:=2 to m do if a[c[i]]*b[i] begin r:=i;t:=a[c[i]]*b[i]; end; if t>a[nt] then begin inc(nt);a[nt]:=t; end; inc(c[r]); end; begin assign(input,'humble.in'); assign(output,'humble.out'); reset(input);rewrite(output); fillchar(a,sizeof(a),0);a[0]:=1; fillchar(b,sizeof(b),0); fillchar(c,sizeof(c),0); readln(m,n); for i:=1 to m do read(b); nt:=0; repeat work until nt=n; writeln(a[n]); close(input);close(output); end. Section 3.1.4 Shaping Regions 首先要离散化,但n^3无法过最后一个数据,于是就有nlogn的二维线段树的方法或是用堆优化的n^2logn。 n^2nlogn方法: 离散化之后,分成了2n条竖线和2n条横线; 按y轴方向从上到下排序; 枚举每一条竖线,即每两条竖线所夹的区域: 初始化堆为空,当前的第一个矩形为排序后最上面那个矩形; 枚举概该竖形区域中的每一个横条: 若当前矩形不再在该竖形区域内,则直接跳过,矩形数+1(即查看下一个矩形); 若当前矩形的上边与该横条重合,则加到堆顶,矩形数+1; 若当前矩形的下边与该横条重合,则从堆中删除,矩形数+1; 判断现堆顶是否有元素,该两条竖线与两条横线所夹小区域颜色即为堆顶元素(矩形)颜色; 最后枚举每一种颜色,若有面积则输出。 Section 3.1.5 Contact 二进制转换成十进制来做. 为了区分0和00这一类的情况,在转换的时候每个二进制前面都+个1. 转换完了以后统计再转换回来就可以了。 Section 3.1.6 Stamps 用f[i]表示面值为i时最少需用几张邮票; 枚举i,先用可行性转移判断是否能凑成面值i,然后f[i]=min{f[j]+f[i-j] (j:=0 to i div 2 do}; 直到不能凑成面值i或是f[i]>k。 April 18 Shaping Regions (USACO)这道题用堆优化太科学了虽然是O(n^2logn),但比二维线段树O(nlogn)写起来简单多了(当然,首先要离散化) Your program ('rect1') produced all correct answers! This is your
submission #6 for this problem. Congratulations!
March 30 USACO Section 2 的部分题解2.1.1_The Castle 前两问用Floodfill解决,对于后两问,枚举当改变某一面墙时,判断所连接的两个房间大小room1+room2是否大于最大房间面积,枚举顺序为按列从左下至右上,先改变靠西的墙再改变靠北的墙。 2.1.2_Ordered Fractions 枚举分子i与分母j, 若GCD(i,j)=1 则 输出。 2.1.3_Sorting A Three-Valued Sequence 将序列排序,设 Hv[i,j] i段中j的数量。当i,j分别等于1,2 1,3 2,3时应交换的次数为 t = min(Hv[i,j],Hv[j,i]) , dec (Hv[i,j],t) , dec(Hv[j,i],t) ,最后剩下的肯定是三段需要同时交换,在总次数中加入(Hv[i,j]+Hv[j,i])*2, i,j可为任意值。 2.1.4_Healthy Holsteins 很显然,对于每种维他命只有选或不选两种状态,时间复杂度为O(2^25),在可以承受的范围之内,直接枚举即可。 2.1.5_Hamming Codes 检查0至2^b-1的数,很显然0必然在答案序列中,对于之后所加入的每一个数,若它与前面所选的数的 hamming code 大于等于D,则加入答案序列中。在检查任意两个数 a,b 的 hamming code 时只需计算 a xor b 的值的二进制编码中1的个数。 2.2.3_Runaround Numbers 这道题其实没什么难度,把原串copy几遍然后按照规则走一遍即可检测出是否符合题意,但是在做的过程中发现有很多细节需要 注意: 1.在检查是否有重复数字出现时,用chos[i](i='0','1'..'9')的boolean数组来存储i是否出现,当发现将要存入的i的chos[i] =true时,直接exit(false); 2.同样的,在检查是否所有数字都已经被选择了时,也用chos[i]来存储i是否出现,最后按原串扫一遍,若有数字k的chos[k] =false,则exit(false); 2.2.3_Subset Sums 动态转移方程 (方程很简单,但是dp状态搜索顺序很重要) 设f(x)表示 元素和为x的子集的个数 则 f(x)=f(x-1)+f(x-2)+f(x-3)....+f(s-s) f(0)=1 状态搜索顺序见代码... s:=(n+1)*n div 2; m[0]:=1; if not odd(s) then begin s:=s div 2; for i:=1 to n do for j:=s downto i do inc(m[j],m[j-i]); writeln(m[s] div 2); end else writeln(0); 2.2.1_Preface Numbering 没什么难度 主要就是arabic转化成roman 对于任意一个阿拉伯数字 1,4,5,9,10,40,50,90,100,400,500,900,1000 从大到小挨个减 获得每一位的roman字符 统计个数 输出 2.2.4_Party Lamps 显然对于每个操作进行2n次将不会改变灯的状态 因此实际枚举量只有2^4次 即不同的操作方案[1,2,3,4,12,13,14,23,123......(每种方案保存按下哪几个按钮)] 对于每种方案 若(c-f(i)) mod 2=0 (f(i) 为第i种方案按下按钮的次数)且 操作后满足题中的最后状态则 加入结果中 最后对结果排序输出 2.3.1_The Longest Prefix 模拟 从需要匹配的串考虑 还可以用dp解决 2.3.2_Cow Pedigrees f[i,j] 表示i个节点最多高度j时的方案数 n个节点 高度k f[i,j]=∑(f[p,j-1]*f[i-1-p,j-1]) (j=1..k,i=2..n,p=1..i-2) 根据乘法原理 以当前节点为根的方案数=左子树的方案数×右子树的方案数 ans=f[n,k]-f[n,k-1] 即恰好n节点k高度时的方案数 2.3.3_Zero Sum 简单的搜索 数据很弱 枚举每一位的操作符 2.3.4_Money Systems f[v,n] 边界f[i,0]=1 (i=0..v) f[i-1,j] (j-coin[i]<0) f[i,j]= f[i-1,j]+f[i,j-coin[i]] (j-coin[i]>=0) 2.3.5_Controlling Companies 就直接模拟(要进行多次) February 21 顺利的开头真想不到USACO注册后交的5道题竟都是直接AC,或许一开始都很简单吧。也是,似乎其他OJ也这样,一开始先easy点,后面就来点什么“一道简单题”之类的BT题(同济上的)。不过,现在做USACO还挺好耍的。 February 20 翻译问题解决了偶然发现USACO译题网站挺有用的http://www.wzoi.org/usaco/,虽然顺序好像和原网站有点不同,但大多数题都翻译了的。这样就不用担心翻译软件差的问题了,在译题网站上查就是了。哎,之前不管用什么翻译动让人头痛,特别是那个“Friday the Thirteenth"翻译得莫名其妙,不过这个词也是莫名其妙。后来看了译题网站的翻译才恍然明白原来是“黑色星期五”,还有很多地方都是这样,有些语句翻译得根本不通顺,还是由人亲自来翻译才是最科学的呀。总之,以后就可以不用担心由于英语差而读不懂的情况了。
首次接触USACO全是英文,看起来真恼火,哎,翻译软件翻译得语句不通,还不如自己读。注册后交了3道题都过了,那里和其他中国的OJ有点不同,在USACO上只能是按顺序做,过了这一道题后才能做下一道题。好像交了题之后都会把输入数据给你,但是网站申明不能直接交表,一旦查出就会封号。总的感觉还是挺不错的,只是希望是中文或有一款更好的翻译软件就好了。 |
|
|