首页 > 代码库 > USACO 2.1
USACO 2.1
USACO 2.1.1
题解:
这题有点毒,调了一个中午……
先读入,用一个三维布尔数组储存第(i,j)个点的四个方向是否有墙。
对于第一个问题,直接BFS求连通块,并构造出一个图,第(i,j)个点的数字表示该房间属于第几个连通块。
对于第二个问题,边BFS边统计。
对于第三个问题,直接暴力枚举每面墙,找最大值。
对于第四个问题,同样是暴力枚举,但要考虑优先级问题。从右上角的房间枚举到左下角的房间(j=m downto 1;i=1 to n),每个房间先看东墙再看北墙。
代码:
{ID:m1599491PROG:castleLANG:PASCAL}const fx:array[1..4] of longint=(0,-1,0,1);const fy:array[1..4] of longint=(-1,0,1,0);var k:array[1..50,1..50,1..4] of boolean;var n,m,i,j,x,tot,l,maxx,ans1,ans2,ans3,p:longint;var num:array[1..2500] of longint;var f:array[1..1000,1..2] of longint;var b,t:array[1..100,1..100] of longint;function max(x,y:longint):longint; begin if x>y then exit(x);exit(y); end;procedure bfs(x,y,tot:longint);var i,j,front,rear,nx,ny:longint;begin front:=0;rear:=1; f[rear,1]:=x;f[rear,2]:=y; b[x,y]:=tot; num[tot]:=1; maxx:=max(maxx,num[tot]); while front<rear do begin inc(front); for i:=1 to 4 do begin nx:=f[front,1];ny:=f[front,2]; if (not k[nx,ny,1])and(i=1) then ny:=ny-1; if (not k[nx,ny,2])and(i=2) then nx:=nx-1; if (not k[nx,ny,3])and(i=3) then ny:=ny+1; if (not k[nx,ny,4])and(i=4) then nx:=nx+1; if (nx>0)and(ny>0)and(nx<=n)and(ny<=m)and(b[nx,ny]=0) then begin inc(rear); f[rear,1]:=nx;f[rear,2]:=ny; b[nx,ny]:=tot; inc(num[tot]); maxx:=max(maxx,num[tot]); end; end; end;end;procedure o;var i,j,t,nx,ny:longint;begin for j:=m downto 1 do for i:=1 to n do begin for t:=3 downto 2 do begin nx:=i+fx[t];ny:=j+fy[t]; if b[nx,ny]=b[i,j] then continue; if (nx<1)or(ny<1)or(nx>n)or(ny>m) then continue; if num[b[i,j]]+num[b[nx,ny]]=p then begin ans1:=i;ans2:=j;ans3:=t; end; end; end;end;function find(x:longint):longint;var i,j,t,nx,ny,merge:longint;begin merge:=-maxlongint; for j:=1 to m do for i:=1 to n do begin for t:=4 downto 1 do begin nx:=i+fx[t];ny:=j+fy[t]; if (nx<1)or(ny<1)or(nx>n)or(ny>m) then continue; if (k[i,j,t])and(b[i,j]<>b[nx,ny]) then if merge<=num[b[i,j]]+num[b[nx,ny]] then merge:=num[b[i,j]]+num[b[nx,ny]]; end; end; exit(merge);end;begin assign(input,‘castle.in‘);reset(input); assign(output,‘castle.out‘);rewrite(output); readln(m,n); for i:=1 to n do begin for j:=1 to m do begin read(x); t[i,j]:=x; if x=1 then k[i,j,1]:=true; if x=2 then k[i,j,2]:=true; if x=4 then k[i,j,3]:=true; if x=8 then k[i,j,4]:=true; if x=3 then begin k[i,j,1]:=true;k[i,j,2]:=true; end; if x=5 then begin k[i,j,1]:=true;k[i,j,3]:=true; end; if x=9 then begin k[i,j,1]:=true;k[i,j,4]:=true; end; if x=6 then begin k[i,j,2]:=true;k[i,j,3]:=true; end; if x=10 then begin k[i,j,2]:=true;k[i,j,4]:=true; end; if x=12 then begin k[i,j,3]:=true;k[i,j,4]:=true; end; if x=7 then begin k[i,j,1]:=true;k[i,j,2]:=true;k[i,j,3]:=true; end; if x=11 then begin k[i,j,1]:=true;k[i,j,2]:=true;k[i,j,4]:=true; end; if x=14 then begin k[i,j,2]:=true;k[i,j,3]:=true;k[i,j,4]:=true; end; if x=13 then begin k[i,j,1]:=true;k[i,j,3]:=true;k[i,j,4]:=true; end; if x=15 then begin k[i,j,1]:=true;k[i,j,2]:=true;k[i,j,3]:=true;k[i,j,4]:=true; end; end; readln; end; maxx:=0; for i:=1 to n do for j:=1 to m do if b[i,j]=0 then begin inc(tot); bfs(i,j,tot); end; writeln(tot); writeln(maxx); p:=find(0);o; writeln(p); if ans3=3 then writeln(ans1,‘ ‘,ans2,‘ E‘); if ans3=2 then writeln(ans1,‘ ‘,ans2,‘ N‘); close(input);close(output);end.
USACO 2.1.2
题解:
暴枚每一种不大于1的分数情况,边判个GCD是不是等于1,接着快排一下出答案。
代码:
{ID:m1599491PROG:frac1LANG:PASCAL}var z:array[1..100000] of double;var x,y:array[1..100000] of longint;var i,n,j,tot:longint;function gcd(a,b:longint):longint;begin if b=0 then exit(a); gcd:=gcd(b,a mod b);end;procedure qs(l,r:longint);var i,j,p:longint;var m,t:double;begin i:=l;j:=r;m:=z[(l+r)>>1]; repeat while z[i]<m do inc(i);while z[j]>m do dec(j); if i<=j then begin t:=z[i];z[i]:=z[j];z[j]:=t; p:=x[i];x[i]:=x[j];x[j]:=p; p:=y[i];y[i]:=y[j];y[j]:=p; inc(i);dec(j); end; until i>j; if i<r then qs(i,r);if l<j then qs(l,j);end;begin assign(input,‘frac1.in‘);reset(input); assign(output,‘frac1.out‘);rewrite(output); readln(n); for i:=0 to n do for j:=1 to n do if (gcd(i,j)=1)and(i/j<=1) then begin inc(tot); x[tot]:=i;y[tot]:=j;z[tot]:=i/j; end; qs(1,tot); for i:=1 to tot do writeln(x[i],‘/‘,y[i]); close(input);close(output);end.
USACO 2.1.3
题解:
列出排序后的数组,判断一下就行。
代码:
{ID:m1599491PROG:sort3LANG:PASCAL}var nn,ans,i,j,n,t:longint;var a,b,num:array[1..1001] of longint;begin assign(input,‘sort3.in‘);reset(input); assign(output,‘sort3.out‘);rewrite(output); readln(n); for i:=1 to n do begin readln(a[i]); inc(num[a[i]]); end; for i:=1 to num[1] do b[i]:=1; for i:=num[1]+1 to num[1]+num[2] do b[i]:=2; for i:=num[1]+num[2]+1 to n do b[i]:=3; for i:=1 to n do for j:=1 to n do if (a[i]<>a[j])and(b[i]=a[j])and(b[j]=a[i]) then begin t:=a[i];a[i]:=a[j];a[j]:=t;inc(nn); end; for i:=1 to n do if a[i]<>b[i] then inc(ans); writeln(nn+trunc(ans/3*2)); close(input);close(output);end.
USACO 2.1.4
题解:
深搜,没啥好说的。
代码:
{ID:m1599491PROG:holsteinLANG:PASCAL}var sum,nee,anss,answer:array[1..100] of longint;var a:array[1..100,1..100] of longint;var b:array[1..100] of boolean;var ans,i,j,n,v,g:longint;procedure dfs(tot,dep:longint);var p,t:boolean;var i,j:longint;begin p:=true;t:=false; for i:=1 to v do if sum[i]<nee[i] then p:=false; if p then begin if dep<=ans then begin if dep=ans then for i:=1 to dep do if answer[i]>anss[i] then begin t:=true; break; end; if t then for i:=1 to dep do answer[i]:=anss[i]; if dep<ans then begin for i:=1 to dep do answer[i]:=anss[i]; ans:=dep; end; end;exit; end; for i:=tot+1 to n do begin if not b[i] then begin dep:=dep+1;b[i]:=true;anss[dep]:=i; for j:=1 to v do sum[j]:=sum[j]+a[i,j]; dfs(i,dep);anss[dep]:=0; for j:=1 to v do sum[j]:=sum[j]-a[i,j]; dec(dep);b[i]:=false; end; end;end;begin assign(input,‘holstein.in‘);reset(input); assign(output,‘holstein.out‘);rewrite(output); readln(v);for i:=1 to v do read(nee[i]);readln(n); for i:=1 to n do for j:=1 to v do read(a[i,j]); for i:=1 to 1000 do answer[i]:=maxlongint; ans:=maxlongint;dfs(0,0); write(ans);for i:=1 to ans do write(‘ ‘,answer[i]);writeln; close(input);close(output);end.
USACO 2.1.5
题解:
首先看它二进制编码的位数,则转为十进制最多只有2^b-1个数,接着用一个数组把这些二进制编码储存起来(记得补0),然后上深搜。
代码:
{ID:m1599491PROG:hammingLANG:PASCAL }var n,b,d,i,k,tot:longint;var s:array[0..1000] of ansistring;var ans:array[0..1000] of longint;var e:array[0..1000] of boolean;function ch(n:longint):ansistring;var s:ansistring;begin s:=‘‘; repeat if n and 1=0 then s:=‘0‘+s else s:=‘1‘+s; n:=n>>1; until n=0; while length(s)<b do s:=‘0‘+s; exit(s);end;function pow(x:longint):longint;begin if x=0 then exit(1); pow:=pow(x>>1); pow:=pow*pow; if x and 1=1 then pow:=pow*2;end;function ok(s1,s2:ansistring):boolean;var sum,i:longint;begin sum:=0; for i:=1 to b do begin if s1[i]<>s2[i] then inc(sum); if sum>=d then exit(true); end; exit(false);end;function okk(t:longint):boolean;var i:longint;begin for i:=1 to tot do if not ok(s[t],s[ans[i]]) then exit(false); exit(true);end;procedure o;var i:longint;begin for i:=1 to tot do if (i mod 10=0)or(i=tot) then writeln(ans[i]) else write(ans[i],‘ ‘); close(input);close(output); halt;end;procedure dfs(x,dep:longint);var i:longint;begin if dep>=n then begin if dep=n then o; exit; end; for i:=x+1 to k do begin if (not e[i])and(okk(i)) then begin e[i]:=true; inc(tot);ans[tot]:=i; dfs(i,dep+1); ans[tot]:=0;dec(tot); e[i]:=false; end; end;end;begin assign(input,‘hamming.in‘);reset(input); assign(output,‘hamming.out‘);rewrite(output); readln(n,b,d); k:=pow(b)-1; for i:=0 to k do s[i]:=ch(i); dfs(-1,0);end.
USACO 2.1
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。