1. 一个袋子里有n(n>3)个银币,其中一枚是假币,并且假币和真币一模一样,肉眼很难分辨,目前只知道假币比真币重量轻一点。采用天平称重方式找到这个假币请并给出操作步骤。C语言两种算法代码
时间: 2024-10-22 16:27:51 浏览: 28
n枚硬币中找假币 其中一个为假
4星 · 用户满意度95%
要找到这枚假币,可以使用二分查找法(也称为分治策略),因为这种方法适用于有序数组(在这种情况下,可以认为银币按重量排序)。这里提供一种简化版的操作步骤和两种C语言实现方法:
**操作步骤:**
1. 将所有银币分为三组:A、B和C,每组包含n/3个银币(若n除3余数不为0,则在A组或B组额外加一个银币)。
2. **第一次比较:**将A组和B组放在天平两端。如果平衡,假币在未称量的C组;如果不平衡,假币在较轻的一端。
3. **第二次比较:**取较轻的那一组(如果有),继续将其分为两部分,每部分包含大约n/6个银币。将这两部分与C组的一个部分进行对比。
- 如果天平平衡,假币在剩余未称量的C组的另一半;
- 如果不平衡,假币就在较轻的部分里。
4. **第三次比较:**对于确定含有假币的那半部分,再次分成两份,每份大约n/12个。称量这两份,假币会在较轻的那一小堆里。
5. **第四次比较(如有需要):**重复上述步骤,每次减半,直到找到那枚假币。
**C语言代码1(递归版本)**:
```c
#include <stdio.h>
int find_fake(int *coins, int n, int lighter, int heavier) {
if (n == 1) return lighter; // 如果只剩一个,就是假币
if (n % 2 == 0) { // 如果偶数个,中间那一堆可能是假币
if (lighter < heavier)
return find_fake(coins + n / 2, n / 2, lighter, coins[n / 2]);
else
return find_fake(coins, n / 2, coins[n / 2], heavier);
} else { // 如果奇数个,第一堆或第二堆可能是假币
if (lighter < heavier)
return find_fake(coins + n / 2, n / 2, lighter, coins[n / 2] + 1);
else
return coins[0];
}
}
int main() {
int coins[] = ...; // 初始化你的银币数组
int n = sizeof(coins) / sizeof(coins[0]);
int fake_coin_index = find_fake(coins, n, 0, n - 1);
printf("假币在第%d位置\n", fake_coin_index);
return 0;
}
```
**C语言代码2(迭代版本)**:
```c
#include <stdio.h>
#include <stdlib.h>
int find_fake_iterative(int *coins, int n) {
for (int i = 0; i < n - 1; ++i) {
int lighter = 0, heavier = n - 1;
while (lighter < heavier) {
int mid = (lighter + heavier) / 2;
if (coins[mid] > coins[i]) {
heavier = mid;
} else {
lighter = mid + 1;
}
}
if (coins[lighter] < coins[i]) {
return lighter;
}
}
return n - 1; // 如果没找到更轻的,假币就是最后一个
}
int main() {
int coins[] = ...; // 初始化你的银币数组
int n = sizeof(coins) / sizeof(coins[0]);
int fake_coin_index = find_fake_iterative(coins, n);
printf("假币在第%d位置\n", fake_coin_index);
return 0;
}
```
在这个代码示例中,`find_fake` 和 `find_fake_iterative` 分别是递归和迭代版本的函数,它们会返回假币在数组中的索引。请根据实际需求替换 `coins[]` 为你的银币重量数组。
阅读全文