n枚硬币问题
大致说一下问题,就是在n枚硬币中存在一个假币,但不知道假币比真币中还是轻,你只有一个天秤,要你用最少的比较次数找到假币在哪。
本来的思路是不断二分,如果硬币是偶数枚,那恰好能分成两份,第一次分成的这两份肯定一份重一份轻,并且无法判断假币在哪一份里。
但如果把第一份再二分,如果重量相等的话,假币肯定在第一次二分的第二份里。
重复以上过程,不断递归,肯定能得出结果。
奇数个硬币的话就先去掉一个呗,剩下的就和偶数类似了。
不过百度了一下,发现一个三分然后判断的,本来三分我是一点思路都没有的,就感觉三分那个可厉害。
于是我加上了随机生成硬币之后,就有了如下的代码:
c/c++实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int step = 0;
void solve(int coin[], int n, int p, int q)
{
step=step+1;
if (n < 3){
printf("无法判断\n");
return;
}
if (p == q){
printf("假币的序号为%d, 假币的重量为%d\n", p+1, coin[p]);
}
else if (q - p == 1){
if (p > 0){
if (coin[p] == coin[0]) solve(coin, n, p + 1, q);
else solve(coin, n, p, q - 1);
}
else if (q < n - 1){
if (coin[p] == coin[n - 1]) solve(coin, n, p + 1, q);
else solve(coin, n, p, q - 1);
}
}
else if (p < q){
int temp = (q - p + 1) / 3;
int sum1 = 0, sum2 = 0;
for(int i = 0; i < temp; i++){
sum1 += coin[p + i];
sum2 += coin[q - i];
}
if (sum1 == sum2){//在中间
solve(coin, n, p + temp, q - temp);
}
else{//在两边,不在中间
if (sum1 == coin[p + temp] * temp){//左边的和中间的相等,在右边
solve(coin, n, q - temp + 1, q);
}
else{
solve(coin, n, p, p + temp - 1);
}
}
}
}
int main()
{
int n,sj0,sj1,sj2;
int coins[10000];
scanf("%d",&n);
srand((int)time(NULL));
sj0 = rand()%10;
for(int i = 0; i < n; i++){
coins[i] = sj0;
}
sj1 = rand()%n;
while(1){
sj2 = rand()%10;
if(sj2!=sj0){
break;
}
}
coins[sj1] = sj2;
for(int i = 0; i < n; i++){
printf("%d ",coins[i]);
}
printf("\n");
solve(coins, n, 0, n-1);
printf("%d\n",step);
return 0;
}
那个回答链接在这(16楼):https://bbs.****.net/wap/topics/290004423