12个球问题(不知轻重)

 

问题描述:有12个球,知道其中一个是坏的,但是不知道是轻了还是重了,现有一天平,问能用3次就找出坏球吗?

答案:肯定是可以的

方法:先分成3堆(4,4,4),记做A组,B组,C组

对A组和B组进行测量

若A,B一样重,则问题出在C组,我们从A组中找出3个和C组中找出3个进行称,如果平衡则坏的就是C组剩下的那个了若不平衡,那问题就出在C组的3个中,我们需要观察刚才A3个和C3个称时是C重还是A重,然后我们在这C3个中取出两个进行称,再根据刚才的A3 和C3的轻重判断出哪个是坏的了。

若A。B不一样重,那么坏球就存在于A.B组中。我们观察A4和B4哪边重,然后从A组中拿出2个,放在一边,从B组中拿出2个放到A2那边,然后从C组中拿出2个放在B2那边,此时观察天平的方向,若天平是平的,那么坏球就在拿出去的A组的两个里面,我们可以根据A4和B4的朝向再随便找一个好球来在称一次找出坏球。若第二次的A4和B4仍不平衡,那么我们再根据第一次和第二次天平的朝向来判断是A2是坏球还是B2是坏球,并且可以判断出坏球是轻了还是重了。然后使用和刚才第三次一样的方法找出坏球。

综上:这个问题是可以解决的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
减治法是一种常见的算法设计思想,它通常用于解决问题的规模较大时,将问题分解为多个子问题,通过解决子问题来解决原问题。在解决n枚假币问题时,可以采用减治法的思想。 具体实现过程如下: 1. 将n枚假币按照相等的两份分为两组,如果n为奇数,则其中一组多一枚假币。 2. 对两组假币分别进行称重,如果两组重量相等,则说明真币在剩下的n-2个币中,转到最后一步。 3. 如果两组重量不相等,则说明较轻的一组中有假币,而较重的一组中可能有假币,也可能全是真币。这时,将较轻的一组假币仍按照相等的两份分为两组,重复执行步骤1和步骤2。 4. 当只剩下2个币时,将它们分别与一枚真币进行称重,如果两个币的重量相等,则说明另一枚真币就是假币,而如果两个币的重量不相等,则轻的一枚就是假币。 下面是Java代码实现: ```java public class FakeCoin { // 假币数量 private static final int NUM = 16; // 假币数组,假币为true,真币为false private static boolean[] coins = new boolean[NUM]; /** * 随机选择一枚假币 */ private static void selectFakeCoin() { Random random = new Random(); int fakeIndex = random.nextInt(NUM); coins[fakeIndex] = true; System.out.println("Fake coin index: " + fakeIndex); } /** * 称重函数 * @param start 起始下标 * @param end 结束下标 * @return -1表示左侧轻,0表示两侧重量相等,1表示右侧轻 */ private static int weigh(int start, int end) { int leftWeight = 0; int rightWeight = 0; for (int i = start; i < end; i++) { if (coins[i]) { leftWeight++; } else { rightWeight++; } } if (leftWeight > rightWeight) { return -1; } else if (leftWeight == rightWeight) { return 0; } else { return 1; } } /** * 减治法解决n枚假币问题 * @param start 起始下标 * @param end 结束下标 * @return 假币下标 */ private static int findFakeCoin(int start, int end) { if (start == end) { return start; } int length = end - start; if (length == 1) { if (weigh(start, end + 1) == 0) { return -1; } else { return start; } } int mid = (start + end) / 2; int leftResult = weigh(start, mid); int rightResult = weigh(mid + 1, end); if (leftResult == 0 && rightResult == 0) { return mid + 1; } else if (leftResult == 0 && rightResult == -1) { return findFakeCoin(mid + 1, end); } else if (leftResult == 0 && rightResult == 1) { return findFakeCoin(start, mid); } else if (leftResult == -1 && rightResult == 0) { return findFakeCoin(start, mid); } else if (leftResult == -1 && rightResult == -1) { return findFakeCoin(start, mid); } else if (leftResult == -1 && rightResult == 1) { return findFakeCoin(start, mid); } else if (leftResult == 1 && rightResult == 0) { return findFakeCoin(mid + 1, end); } else if (leftResult == 1 && rightResult == -1) { return findFakeCoin(start, mid); } else { return findFakeCoin(mid + 1, end); } } public static void main(String[] args) { selectFakeCoin(); int fakeIndex = findFakeCoin(0, NUM - 1); if (fakeIndex == -1) { System.out.println("No fake coin found."); } else { System.out.println("Fake coin found at index: " + fakeIndex); } } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值