USACO 2.1

USACO 2.1.1 

题解:

这题有点毒,调了一个中午……

先读入,用一个三维布尔数组储存第(i,j)个点的四个方向是否有墙。

对于第一个问题,直接BFS求连通块,并构造出一个图,第(i,j)个点的数字表示该房间属于第几个连通块。

对于第二个问题,边BFS边统计。

对于第三个问题,直接暴力枚举每面墙,找最大值。

对于第四个问题,同样是暴力枚举,但要考虑优先级问题。从右上角的房间枚举到左下角的房间(j=m downto 1;i=1 to n),每个房间先看东墙再看北墙。

代码:

{
ID:m1599491
PROG:castle
LANG: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:m1599491
PROG:frac1
LANG: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:m1599491
PROG:sort3
LANG: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:m1599491
PROG:holstein
LANG: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:m1599491
PROG:hamming
LANG: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

 

posted @ 2017-04-14 12:45  ALHDLIOX  阅读(148)  评论(0编辑  收藏  举报