找回密码
 欢迎注册
楼主: mathematica

[提问] 求水杯问题的终极解答!

[复制链接]
发表于 2017-4-12 10:48:08 | 显示全部楼层
第一个问题,三只杯子只要定好出入方向,B12总是以B8和B5整杯出入,总能达到结果。所谓定好方向,就是过程中A杯与B杯若有授受,只能是A杯倒向B杯,不能反之。
只有两个方向:顺向(B12→B8→B5→B12),逆向(B12→B5→B8→B12)
顺向M10程序及结果:
  1. NestWhileList[
  2. Which[
  3.    First@# == 0, # + {8, -8, 0},(*若B8为空,则用它从B12中量出8升水*)
  4.    Last@# == 5, # + {0, 5, -5},(*若B5装满,则将B5全部倒入B12*)
  5.    True, # + {-1, 0, 1} Min[First@#, 5 - Last@#]] &,(*若B8不空,B5不满,则将B8中的水倒入B5,倒空B8或者装满B5*)
  6. {0, 12, 0}, (*{B8, B12, B5}的初值*)
  7. # != {6, 6, 0} & (*{B8, B12, B5}的终值*)
  8. ]
复制代码

Out[1]={{0, 12, 0}, {8, 4, 0}, {3, 4, 5}, {3, 9, 0}, {0, 9, 3}, {8, 1,   3}, {6, 1, 5}, {6, 6, 0}}

逆向M10程序及结果:
  1. NestWhileList[ Which[ Last@# == 0, # + {0, -5, 5}, First@# ==8, # + {-8, 8, 0}, True, # + {1, 0, -1} Min[Last@#, 8 -First@#]] &, {0, 12, 0}, # != {6, 6, 0} &]
复制代码

[Out2]={{0, 12, 0}, {0, 7, 5}, {5, 7, 0}, {5, 2, 5}, {8, 2, 2}, {0, 10, 2}, {2, 10, 0}, {2, 5, 5}, {7, 5, 0}, {7, 0, 5}, {8, 0, 4}, {0, 8, 4}, {4, 8, 0}, {4, 3, 5}, {8, 3, 1}, {0, 11, 1}, {1, 11, 0}, {1, 6, 5}, {6, 6, 0}}

两个方向的输出结果正好包含了全部25个状态。

点评

你写的代码很牛逼,至少我看不懂  发表于 2017-5-24 14:03
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-4-12 11:12:05 | 显示全部楼层
顺向是最短路径,而逆向是最长路径吧。逆向结果中明显可以从{0,7,5}改变方程和定量直接到{7,0,5}.

保持方向和定量的好处就是在你事先不知道路线图时,总能找到终点,不用费神去想什么时候改变策略可有捷径。

如果你没有路线图,又没有规则(方向和定量),随意地变来变去想碰到捷径,就会在迷宫里转圈圈。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2018-7-23 16:17:37 | 显示全部楼层
hujunhua 发表于 2017-4-12 10:48
第一个问题,三只杯子只要定好出入方向,B12总是以B8和B5整杯出入,总能达到结果。所谓定好方向,就是过程 ...

  1. Clear["Global`*"];(*Clear all variables*)
  2. (*水的方向只能是从A到B,从B到C,从C到A这样运行*)
  3. a=32; b=23; c=9;(*三只水杯的容积*)
  4. aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
  5. Do[
  6.     (*如果B杯空了,就把A杯的水倒满B杯*)
  7.     If[bb==0,If[aa<b,Print["BUG!"];Break[]];a2b=b;aa=aa-a2b;bb=bb+a2b;Print@{aa,bb,cc}];
  8.     (*把B杯的水尽可能地倒向C杯*)
  9.     If[cc<c,b2c=Min[bb,c-cc];bb=bb-b2c;cc=cc+b2c;Print@{aa,bb,cc}];
  10.     (*如果C杯满了,就全部倒向A杯*)
  11.     If[cc==c,If[aa+cc>a,Print["BUG!!"];Break[]];c2a=c;aa=aa+c2a;cc=cc-c2a;Print@{aa,bb,cc}];
  12.     If[aa==19,Break[]],
  13.     {k,1,100}
  14. ]
复制代码

如果水的总体积大于最大的水杯的容积,那么如何操作呢?上面的程序就bug了!

运行结果如下:
{32,0,4}
{9,23,4}
{9,18,9}
{18,18,0}
{18,9,9}
{27,9,0}
{27,0,9}

BUG!!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2018-7-23 16:25:08 | 显示全部楼层
a=32; b=23; c=9;(*三只水杯的容积*)
aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
能够做到使得A杯里面水的体积是19吗?


  1. Clear["Global`*"];(*Clear all variables*)
  2. (*水的方向只能是从A到B,从B到C,从C到A这样运行*)
  3. a=32; b=23; c=9;(*三只水杯的容积*)
  4. aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
  5. Do[
  6.     (*如果B杯空了,就把A杯的水倒满B杯*)
  7.     If[bb==0&&aa>=b,a2b=b;aa=aa-a2b;bb=bb+a2b;Print@{aa,bb,cc}];
  8.     (*把B杯的水尽可能地倒向C杯*)
  9.     If[cc<c,b2c=Min[bb,c-cc];bb=bb-b2c;cc=cc+b2c;Print@{aa,bb,cc}];
  10.     (*如果C杯满了,就全部倒向A杯*)
  11.     If[(cc==c)&&(aa+cc<=a),c2a=c;aa=aa+c2a;cc=cc-c2a;Print@{aa,bb,cc}];
  12.     If[aa==19,Break[]],
  13.     {k,1,200}
  14. ]
复制代码

{32,0,4}
{9,23,4}
{9,18,9}
{18,18,0}
{18,9,9}
{27,9,0}
{27,0,9}
{4,23,9}
{13,23,0}
{13,14,9}
{22,14,0}
{22,5,9}
{31,5,0}
{31,0,5}
{8,23,5}
{8,19,9}
{17,19,0}
{17,10,9}
{26,10,0}
{26,1,9}

看这代码的运行结果,似乎没解,但是问题是否有解呢?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2018-7-25 11:09:17 | 显示全部楼层
解方程$32+23x+9y=19$,得$x=1,y=-4$,那么
{32,4,0}
{23,4,9}
{23,13,0}
{14,13,9}
{14,22,0}
{5,22,9}
{5,23,8}
{28,0,8}
{28,8,0}
{19,8,9}

点评

我渐渐明白了,我是按照ABC的顺序倒水,而你是按照ACB的顺序倒水,  发表于 2018-7-28 16:27
有代码吗?  发表于 2018-7-28 16:25
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2022-7-7 15:06:56 | 显示全部楼层
5+(-1)=4,-1=2-3,2=5-3
5L满杯倒入3L满杯,3L杯清空,5L杯子中剩余2L水倒入3L杯,5L杯再倒满,然后往装有2L水的3L杯倒满,剩余即为5L杯中装有4L水。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-8 17:25 , Processed in 0.047248 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表