倒水問題 (codevs 1226) 題解

2022-08-30 12:15:10 字數 3340 閱讀 8538

有兩個無刻度標誌的水壺,分別可裝x公升和y公升 ( x,y 為整數且均不大於100)的水。設另有一水缸,可用來向水壺灌水或接從水壺中倒出的水, 兩水壺間,水也可以相互傾倒。已知x公升壺為空壺, y公升壺為空壺。問如何通過倒水或灌水操作, 用最少步數能在x或y公升的壺中量出 z(z ≤ 100)公升的水來。

3 22 1

14看到求最少步數,馬上想到用廣度優先搜尋,那麼問題在於如何展開?要不要剪枝?其實,這道題是不需要任何剪枝的,只要判重就行了,那麼關鍵就在於如何展開。

對於x壺和y壺,設它們壺中各裝了a,b公升水,那麼一共有以下六種操作:

若a>0且b0時可以反操作。

若a>0時,可將x向水缸中倒出a公升水,此時x中沒有水,y中不變,若b>0時也可反操作。

若a根據這六種操作,我們如何拓展的問題就解決了。

1

uses math;

2type rec=record

3dep,x,y:longint;

4end;5

var a:array[1..1000] of

rec;

6 f:array[0..100,0..100] of

boolean;

7h,r,x,y,z,xx,yy:longint;

8begin

9readln(x,y,z);

10fillchar(f,sizeof(f),true);

11 f[0,0]:=false;

12 h:=0;r:=1;13

while h<>r do

14begin

15inc(h);

16if (a[h].x>=0)and(a[h].y<=y) then

17begin

18inc(r);

19 a[r]:=a[h];

20 a[r].dep:=a[h].dep+1;a[r].x:=a[h].x-min(a[h].x,y-a[h].y);a[r].y:=a[h].y+min(a[h].x,y-a[h].y);

21if

not(f[a[r].x,a[r].y]) then

22dec(r)

23else

24 f[a[r].x,a[r].y]:=false;

25end;26

if (a[r].x=z)or(a[r].y=z) then

27begin

28writeln(a[r].dep);

29exit;

30end;31

if (a[h].x<=x)and(a[h].y>=0) then

32begin

33inc(r);

34 a[r]:=a[h];

35 a[r].dep:=a[h].dep+1;a[r].x:=a[h].x+min(a[h].y,x-a[h].x);a[r].y:=a[h].y-min(a[h].y,x-a[h].x);

36if

not(f[a[r].x,a[r].y]) then

37dec(r)

38else

39 f[a[r].x,a[r].y]:=false;

40end;41

if (a[r].x=z)or(a[r].y=z) then

42begin

43writeln(a[r].dep);

44exit;

45end;46

if a[h].x>=0

then

47begin

48inc(r);

49 a[r]:=a[h];

50 a[r].dep:=a[h].dep+1;a[r].x:=0;51

ifnot(f[a[r].x,a[r].y]) then

52dec(r)

53else

54 f[a[r].x,a[r].y]:=false;

55end;56

if (a[r].x=z)or(a[r].y=z) then

57begin

58writeln(a[r].dep);

59exit;

60end;61

if a[h].x<=x then

62begin

63inc(r);

64 a[r]:=a[h];

65 a[r].dep:=a[h].dep+1;a[r].x:=x;

66if

not(f[a[r].x,a[r].y]) then

67dec(r)

68else

69 f[a[r].x,a[r].y]:=false;

70end;71

if (a[r].x=z)or(a[r].y=z) then

72begin

73writeln(a[r].dep);

74exit;

75end;76

if a[h].y>=0

then

77begin

78inc(r);

79 a[r]:=a[h];

80 a[r].dep:=a[h].dep+1;a[r].y:=0;81

ifnot(f[a[r].x,a[r].y]) then

82dec(r)

83else

84 f[a[r].x,a[r].y]:=false;

85end;86

if (a[r].x=z)or(a[r].y=z) then

87begin

88writeln(a[r].dep);

89exit;

90end;91

if a[h].y<=y then

92begin

93inc(r);

94 a[r]:=a[h];

95 a[r].dep:=a[h].dep+1;a[r].y:=y;

96if

not(f[a[r].x,a[r].y]) then

97dec(r)

98else

99 f[a[r].x,a[r].y]:=false;

100end

;101

if (a[r].x=z)or(a[r].y=z) then

102begin

103writeln(a[r].dep);

104exit;

105end

;106

end;//六種展開方式,每次展開後都要判重,然後看是否達到目標

107 writeln('

impossible');

108end.

CodeVS1226 倒水問題

題目描述 description 有兩個無刻度標誌的水壺,分別可裝 x 公升和 y 公升 x,y 為整數且均不大於 100 的水。設另有一水 缸,可用來向水壺灌水或接從水壺中倒出的水,兩水壺間,水也可以相互傾倒。已知 x 公升壺為空 壺,y 公升壺為空壺。問如何通過倒水或灌水操作,用最少步數能在x或...

倒水問題 (codevs 1226) 題解

問題描述 有兩個無刻度標誌的水壺,分別可裝x公升和y公升 x,y 為整數且均不大於100 的水。設另有一水缸,可用來向水壺灌水或接從水壺中倒出的水,兩水壺間,水也可以相互傾倒。已知x公升壺為空壺,y公升壺為空壺。問如何通過倒水或灌水操作,用最少步數能在x或y公升的壺中量出 z z 100 公升的水來...

CODEVS 倒水問題

題目描述 有兩個無刻度標誌的水壺,分別可裝 x 公升和 y 公升 x,y 為整數且均不大於 100 的水。設另有一水 缸,可用來向水壺灌水或接從水壺中倒出的水,兩水壺間,水也可以相互傾倒。已知 x 公升壺為空 壺,y 公升壺為空壺。問如何通過倒水或灌水操作,用最少步數能在x或y公升的壺中量出 z z...