在120枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较两组硬币,最坏情况下,能不能只比较5次就检测出这枚假币?
时间: 2023-04-25 12:00:40 浏览: 323
可以只比较5次就检测出这枚假币。具体方法如下:
第一次:将硬币分成三组,每组40枚,分别放在天平的左右两边,留下40枚不比较。
第二次:将左右两边的硬币各取20枚,放在天平的左右两边比较,留下20枚不比较。
第三次:将上一次比较较轻的一边的硬币分成两组,每组10枚,放在天平的左右两边比较,留下10枚不比较。
第四次:将上一次比较较轻的一边的硬币各取5枚,放在天平的左右两边比较,留下5枚不比较。
第五次:将上一次比较较轻的一边的硬币各取2枚,放在天平的左右两边比较,留下1枚不比较。如果天平平衡,则留下的那枚硬币是假币;如果天平不平衡,则较轻的一边的那两枚硬币中有一枚是假币,可以通过手感或者再次比较来确定假币的位置和重量。
相关问题
5、在120枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的质量不同,但不知道假币与真币相比是较轻还是较重。可以通过一台天平来任意比较两组硬币,最坏情况下,能不能通过5次检测出这枚假币?C语言实现上面代码
可以的,在最坏的情况下,利用二分法策略,可以在5次称量中找出这枚假币。以下是C语言的一个简单模拟实现:
```c
#include <stdio.h>
int findFakeCoin(int coins[], int n) {
// 初始划分,假设假币在前半部分
int half = n / 2;
for (int i = 0; i <= 4; i++) { // 最坏情况5次
// 称量第i+1组(从0开始计数)
if (i == 4) {
// 如果只剩2枚硬币,一次比较就能确定
if (half == 1) {
return coins[i + 1] != coins[0];
}
} else {
// 分别称量两边重量
int leftWeight = coins[0] + coins[half];
int rightWeight = coins[half + 1] + coins[n - 1];
// 比较两边重量
if (leftWeight > rightWeight) {
// 假币在右半边
half = n - 1 - half;
} else if (leftWeight < rightWeight) {
// 假币在左半边
half -= 1;
} else {
// 如果一样重,说明假币在剩余未比较的那一组
half = half % 2 ? half : half - 1;
}
}
}
// 返回假币索引(因为已经更新到了假币所在的一侧)
return half;
}
int main() {
int coins[] = {100, 99, 101, 100, 100, ...}; // 填充120枚硬币的实际值
int n = sizeof(coins) / sizeof(coins[0]);
int fakeIndex = findFakeCoin(coins, n);
printf("假币位于下标%d处\n", fakeIndex);
return 0;
}
```
这个代码首先将硬币分为两组,每次称量都会把假币所在的那一组进一步缩小范围。注意,当只剩2枚硬币时,一次称量即可确定。如果5次都未能找到,程序会返回假币可能所在的唯一位置。
6、在120枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重 量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较 两组硬币,最坏情况下,能不能只比较5次就检测出这枚假币?
可以只比较5次就检测出这枚假币。
首先将120枚硬币分成三组,每组40枚。
第一步:将第一组和第二组各放在天平的一边,第三组留在一旁。如果天平平衡,则假币在第三组中;否则,假币在较轻的那一组中。
第二步:将第一组中的20枚和第二组中的20枚放在天平的两边比较。如果天平平衡,则假币在第三组中;否则,假币在较轻的那一组中。
第三步:将较轻的一组中的10枚硬币分成两组,每组5枚。将这两组硬币放在天平的两边比较。如果天平平衡,则假币在未比较的5枚硬币中;否则,假币在较轻的那一组中。
第四步:将较轻的一组中的5枚硬币中的3枚放在天平的两边比较。如果天平平衡,则假币在未比较的2枚硬币中;否则,假币在较轻的那一组中。
第五步:将较轻的一组中的2枚硬币中的1枚放在天平的一边,将一枚已知为真币的硬币放在另一边。如果天平平衡,则未被比较过的那枚硬币为假币;否则,较轻的那枚硬币为假币。
阅读全文