分油问题

【题目描述】
设有大小不等的3个无刻度的油桶,分别能够存满,X,Y,Z公升油。初始时,第一个油桶盛满油,第二、三个油桶为空。编程寻找一种最少步骤的分油方式,在某一个油桶上分出targ升油。若找到解,则将分油方法打印出来,否则输出“No Answer!”。
【输入格式】
一行4个整数,依次表示X,Y,Z,targ,每个数之间用一个空格隔开
【输出格式】
表示解的情况,如果无解输出“No Answer!”,如果有解,则输出分油方法(每一步三个油桶的状态),如果解不唯一也只有输出任一个解
【样例输入】
80 50 30 40
【样例输出】
80 0 0
30 50 0
30 20 30
60 20 0
60 0 20
10 50 20
10 40 30
【分析】
广搜,每次搜索6种倒油方案:
A–>B
A–>C
B–>A
B–>C
C–>A
C–>B

var
  q:array[0..10001,1..4]of longint;
    tar:array[1..3]of longint;
    targ,head,tail,flag:longint;

procedure move(a,b,c:longint);
var
  i:longint;
begin
  inc(tail);
    if q[head,a]+q[head,b]>tar[b] then begin
      q[tail,a]:=q[head,a]+q[head,b]-tar[b];
        q[tail,b]:=tar[b];
    end
    else begin
      q[tail,a]:=0;
        q[tail,b]:=q[head,a]+q[head,b];
    end;
    q[tail,c]:=q[head,c];
    q[tail,4]:=head;
    for i:=1 to tail-1 do
      if (q[tail,1]=q[i,1])and(q[tail,2]=q[i,2]) then begin dec(tail);exit; end;
    if (q[tail,a]=targ)or(q[tail,b]=targ) then flag:=1;
end;

procedure print(step:longint);
begin
  if q[step,4]<>0 then print(q[step,4]);
  writeln(q[step,1],' ',q[step,2],' ',q[step,3]);
end;

begin
  read(tar[1],tar[2],tar[3],targ);
    q[1,1]:=tar[1]; q[1,2]:=0; q[1,3]:=0; q[1,4]:=0;
    flag:=0;
    head:=1;tail:=1;
    while (head<=tail)and(flag=0) do begin
        if (q[head,1]>0)and(flag=0) then move(1,2,3);
        if (q[head,1]>0)and(flag=0) then move(1,3,2);
        if (q[head,2]>0)and(flag=0) then move(2,1,3);
        if (q[head,2]>0)and(flag=0) then move(2,3,1);
        if (q[head,3]>0)and(flag=0) then move(3,1,2);
        if (q[head,3]>0)and(flag=0) then move(3,2,1);
        inc(head);
    end;
    if head>tail then begin write('No Answer!');exit; end;
    print(tail);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值