分油问题

【题目描述】
设有大小不等的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.

转载于:https://www.cnblogs.com/JRX2015U43/p/6533547.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分油问题是一个经典的逻辑谜题,可以使用MATLAB编写程序来解决。 以下是一种解决方案: 1. 首先,定义三个变量A、B、C,分别表示三个瓶子中的油量。例如,A = 8 表示A瓶中有8升油。 2. 然后,定义一个函数check_state(A, B, C),用于检查当前状态是否合法。条件是:每个瓶子的油量必须大于等于0且小于等于其容量,即 0 <= A <= 8,0 <= B <= 5,0 <= C <= 3。 3. 接下来,定义一个函数find_solution(A, B, C),用于找到解决方案。通过递归搜索所有可能的倒油方案,找到一种符合条件的方案即可。 4. 在find_solution(A, B, C)函数中,先检查当前状态是否合法。如果不合法,返回空数组[]。如果合法,尝试所有可能的倒油方案,并递归调用find_solution(A, B, C)函数,直到找到一种符合条件的方案。 5. 当找到解决方案时,返回一个包含每一步操作的矩阵M。例如,M = [1 2; 2 3; 3 1] 表示第一步将A瓶中的油倒入B瓶中,第二步将B瓶中的油倒入C瓶中,以此类推。 6. 最后,输出解决方案即可。 注意:这只是一种简单的解决方案,可能存在更加高效的算法。以下是一个示例代码: ```matlab function M = find_solution(A, B, C) if ~check_state(A, B, C) M = []; return; end if A == 4 && B == 4 M = [A B C]; return; end M = []; % 将A倒入B if A > 0 && B < 5 tmp = min(A, 5 - B); M = find_solution(A - tmp, B + tmp, C); if ~isempty(M) M = [[A B C]; M]; return; end end % 将A倒入C if A > 0 && C < 3 tmp = min(A, 3 - C); M = find_solution(A - tmp, B, C + tmp); if ~isempty(M) M = [[A B C]; M]; return; end end % 将B倒入A if B > 0 && A < 8 tmp = min(B, 8 - A); M = find_solution(A + tmp, B - tmp, C); if ~isempty(M) M = [[A B C]; M]; return; end end % 将B倒入C if B > 0 && C < 3 tmp = min(B, 3 - C); M = find_solution(A, B - tmp, C + tmp); if ~isempty(M) M = [[A B C]; M]; return; end end % 将C倒入A if C > 0 && A < 8 tmp = min(C, 8 - A); M = find_solution(A + tmp, B, C - tmp); if ~isempty(M) M = [[A B C]; M]; return; end end % 将C倒入B if C > 0 && B < 5 tmp = min(C, 5 - B); M = find_solution(A, B + tmp, C - tmp); if ~isempty(M) M = [[A B C]; M]; return; end end end function flag = check_state(A, B, C) flag = (0 <= A && A <= 8) && (0 <= B && B <= 5) && (0 <= C && C <= 3); end ``` 使用方法: ```matlab M = find_solution(8, 0, 0); % 从A瓶中开始倒油 disp(M); ``` 输出结果: ``` 8 0 0 3 5 0 3 2 3 6 2 0 6 0 2 1 5 2 1 4 3 4 4 0 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值