分酒问题java代码_算法笔记_219:泊松分酒(Java)

该博客介绍了泊松分酒问题,一个涉及容器和油量分配的数学问题。使用Java编程解决这个问题,用户输入容器容量和初始油量,程序通过计算输出实现目标油量的一种操作步骤。博客提供了一个具体的Java代码实现,展示了如何通过不同容器之间的倒油操作达到目标状态。

1 问题描述

泊松是法国数学家、物理学家和力学家。他一生致力科学事业,成果颇多。有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布。

有一次闲暇时,他提出过一个有趣的问题,后称为:“泊松分酒”。在我国古代也提出过类似问题,遗憾的是没有进行彻底探索,其中流传较多是:“韩信走马分油”问题。

有3个容器,容量分别为12升,8升,5升。其中12升中装满油,另外两个空着。要求你只用3个容器操作,最后使得某个容器中正好有6升油。

下面的列表是可能的操作状态记录:

12,0,0

4,8,0

4,3,5

9,3,0

9,0,3

1,8,3

1,6,5

每行3个数据,分别表示12,8,6升容器中的油量

第一行表示初始状态,第二行表示把12升倒入8升容器后的状态,第三行是8升倒入5升,...

当然,同一个题目可能有多种不同的正确操作步骤。

本题目的要求是,请你编写程序,由用户输入:各个容器的容量,开始的状态,和要求的目标油量,程序则通过计算输出一种实现的步骤(不需要找到所有可能的方法)。如果没有可能实现,则输出:“不可能”。

例如,用户输入:

12,8,5,12,0,0,6

用户输入的前三个数是容器容量(由大到小),接下来三个数是三个容器开始时的油量配置,最后一个数是要求得到的油量(放在哪个容器里得到都可以)

则程序可以输出(答案不唯一,只验证操作可行性):

12,0,0

4,8,0

4,3,5

9,3,0

9,0,3

1,8,3

1,6,5

每一行表示一个操作过程中的油量状态。

注意:

请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!

2 解决方案

1 importjava.util.ArrayList;2 importjava.util.Scanner;3

4 public classMain {5 public static ArrayList set = new ArrayList();6 public static int[] maxN = new int[3];7 public static int[] N = new int[3];8 public static intans;9 public static int count = 0;10

11 //某start瓶向end瓶中倒

12 public void getOnetoAnother(int start, intend) {13 if(N[start] == 0)14 return;15 if(maxN[end] >N[end]) {16 int low = maxN[end] -N[end];17 int temp1 = N[start], temp2 =N[end];18 if(low >=N[start]) {19 N[end] = N[end] +N[start];20 N[start] = 0;21 } else{22 N[end] =maxN[end];23 N[start] = N[start] -low;24 }25 StringBuffer s = new StringBuffer("");26 s.append(N[0]);27 s.append(",");28 s.append(N[1]);29 s.append(",");30 s.append(N[2]);31 if(!set.contains(s.toString())) {32 set.add(s.toString());33 count++;34 } else{35 N[start] =temp1;36 N[end] =temp2;37 }38 }39 }40

41 public booleancheck() {42 if(N[0] == ans || N[1] == ans || N[2] ==ans) {43 for(String s : set)44 System.out.println(s);45 return true;46 }47 return false;48 }49

50 public voidgetResult() {51 int max = Math.max(maxN[0], Math.max(maxN[1], maxN[2]));52 if(ans >max) {53 System.out.println("不可能");54 return;55 }56 while(true) {57 int temp =count;58 //A瓶向B瓶倒

59 getOnetoAnother(0, 1);60 if(check())61 break;62 //B瓶向C瓶倒

63 getOnetoAnother(1, 2);64 if(check())65 break;66 //C瓶向A瓶倒

67 getOnetoAnother(2, 0);68 if(check())69 break;70 //A瓶向C瓶倒

71 getOnetoAnother(0, 2);72 if(check())73 break;74 //C瓶向B瓶倒

75 getOnetoAnother(2, 1);76 if(check())77 break;78 //B瓶向A瓶倒

79 getOnetoAnother(1, 0);80 if(check())81 break;82 temp = count -temp;83 if(temp == 0) {84 System.out.println("不可能");85 return;86 }87 }88 }89

90 public static voidmain(String[] args) {91 Main test = newMain();92 Scanner in = newScanner(System.in);93 String S =in.next();94 String[] arrayS = S.split(",");95 for(int i = 0;i < 3;i++)96 maxN[i] =Integer.valueOf(arrayS[i]);97 for(int i = 3;i < 6;i++)98 N[i - 3] =Integer.valueOf(arrayS[i]);99 ans = Integer.valueOf(arrayS[6]);100 StringBuffer s = new StringBuffer("");101 s.append(N[0]);102 s.append(",");103 s.append(N[1]);104 s.append(",");105 s.append(N[2]);106 set.add(s.toString());107 test.getResult();108 }109 }

运行结果:

测试用例1:12,8,5,12,0,0,6

12,0,0

4,8,0

4,3,5

9,3,0

9,0,3

7,0,5

7,5,0

2,5,5

2,8,2

10,0,2

10,2,0

5,2,5

5,7,0

0,7,5

0,8,4

8,0,4

8,4,0

3,4,5

3,8,1

11,0,1

11,1,0

6,1,5测试用例2:30,13,7,30,0,0,5

30,0,0

17,13,0

17,6,7

24,6,0

24,0,6

23,0,7

23,7,0

16,7,7

16,13,1

29,0,1

29,1,0

22,1,7

22,8,0

15,8,7

15,13,2

28,0,2

28,2,0

21,2,7

21,9,0

14,9,7

14,13,3

27,0,3

27,3,0

20,3,7

20,10,0

13,10,7

13,13,4

26,0,4

26,4,0

19,4,7

19,11,0

12,11,7

12,13,5测试用例3:31,19,11,31,0,0,5

31,0,0

12,19,0

12,8,11

23,8,0

23,0,8

20,0,11

20,11,0

9,11,11

9,19,3

28,0,3

28,3,0

17,3,11

17,14,0

6,14,11

6,19,6

25,0,6

25,6,0

14,6,11

14,17,0

3,17,11

3,19,9

22,0,9

22,9,0

11,9,11

11,19,1

30,0,1

30,1,0

19,1,11

19,12,0

8,12,11

8,19,4

27,0,4

27,4,0

16,4,11

16,15,0

5,15,11测试用例4:65,33,12,65,0,0,18

65,0,0

32,33,0

32,21,12

44,21,0

44,9,12

56,9,0

56,0,9

53,0,12

53,12,0

41,12,12

41,24,0

29,24,12

29,33,3

62,0,3

62,3,0

50,3,12

50,15,0

38,15,12

38,27,0

26,27,12

26,33,6

59,0,6

59,6,0

47,6,12

47,18,0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值