usaco 1.4.4——milk3

Mother's Milk 母亲的牛奶

描述

农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的。有时,约翰把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约,牛奶不会有丢失。

写一个程序去帮助约翰找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。

格式

PROGRAM NAME: milk3

INPUT FORMAT:

(file milk3.in)

单独的一行包括三个整数A,B和C。

OUTPUT FORMAT:

(file milk3.out)

只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性。

SAMPLE INPUT 1

8 9 10

SAMPLE OUTPUT 1

1 2 8 9 10

SAMPLE INPUT 2

2 5 10

SAMPLE OUTPUT 2

5 6 7 8 9 10

 
     

漂亮啊。

这个时间效率。。。

     

Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 2288 KB] Test 2: TEST OK [0.000 secs, 2288 KB] Test 3: TEST OK [0.000 secs, 2288 KB] Test 4: TEST OK [0.000 secs, 2288 KB] Test 5: TEST OK [0.000 secs, 2288 KB] Test 6: TEST OK [0.000 secs, 2288 KB] Test 7: TEST OK [0.000 secs, 2288 KB] Test 8: TEST OK [0.000 secs, 2288 KB] Test 9: TEST OK [0.000 secs, 2288 KB] Test 10: TEST OK [0.000 secs, 2288 KB] All tests OK.

Your program ('milk3') produced all correct answers! This is your submission #5 for this problem. Congratulations!

 

分析:

这道题的话,其实我开始还是暴力搜索啊。。。

我开始卡搜索层数,结果第三个点就崩了。。。

然后我放宽了一层,第三个点超时。。。

最终,我无可奈何地去想如何剪枝,

我注意到数不大,于是用了个三维的数组做标记,

防止重复搜索的发生,

结果搜索效率大大提升(而且为了不漏解,我把搜索层数从12层改到了50层。。。。)

如上图。。

(最最后还要提醒一点,要用writeln,。。。要不usaco算错啊亲。。)

 

{
ID: codeway3
PROG: milk3
LANG: PASCAL
}
program milk3;
  var
    i,j,n,m,k,l,a,b,c:longint;
    d:array[0..100]of integer;
    dd:array[0..100,0..100,0..100]of integer;
  function min(x,y:longint):longint;
    begin
      if x<y then exit(x);
      exit(y);
    end;

  procedure doing(aa,bb,cc,js:longint);
    var
      i,j,z:longint;
    begin
      if dd[aa,bb,cc]=1 then exit;
      dd[aa,bb,cc]:=1;
      if js>50 then exit;
      inc(js);
      if aa=0 then begin d[cc]:=1;if cc>l then l:=cc;end;
      if (aa<>0)or(bb<>0) then
        begin
          if bb<>b then doing(aa-min(aa,b-bb),bb+min(aa,b-bb),cc,js);
          if aa<>a then doing(aa+min(a-aa,bb),bb-min(a-aa,bb),cc,js);
        end;
      if (aa<>0)or(cc<>0) then
        begin
          if aa<>a then doing(aa+min(a-aa,cc),bb,cc-min(a-aa,cc),js);
          if cc<>c then doing(aa-min(aa,c-cc),bb,cc+min(aa,c-cc),js);
        end;
      if (bb<>0)or(cc<>0) then
        begin
          if bb<>b then doing(aa,bb+min(b-bb,cc),cc-min(b-bb,cc),js);
          if cc<>c then doing(aa,bb-min(bb,c-cc),cc+min(bb,c-cc),js);
        end;
    end;

  begin
    assign(input,'milk3.in');
    reset(input);
    assign(output,'milk3.out');
    rewrite(output);
    readln(a,b,c);
    doing(0,0,c,0);
    for i:=0 to l-1 do if d[i]=1 then write(i,' ');
    writeln(l);
    close(input);
    close(output);
  end.

posted on 2011-10-22 15:11  codeway3  阅读(325)  评论(0编辑  收藏  举报

导航