首页 > 代码库 > 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.
The Castle

 

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.
Ordered Fractions

 

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.
Sorting a Three-Valued Sequence

 

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.
Healthy Holsteins

 

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.
Hamming Codes

 

USACO 2.1