转载请注明出处,谢谢~
背景说明:
现有八枚硬币a,b,c,d,e,f,g,h,已知其中一枚硬币是假币,其重量不同于真币,但不知道它是轻还是重,如何使用天平,以最少的比较次数,判断哪枚硬币是假币,并得知它是轻还是重。
不用白话文解释了吧。。。
首先果断放弃两两比较的方法,可行但肯定不是最快解。
这里我们用分段处理,将8个硬币分成三组,第一组是1,2,3;第二组是4,5,6;第三组是7,8.我们比较前两组的重量,如果相等,那么假币就存在与第三组中,再次比较第三组中两个硬币的重量,然后将较重的一个跟第一个硬币比较重量,就可以得知那个硬币是假币,并且得知轻重了,其他的情况于此类此,下面用代码走一遍看看逻辑执行。
void compare(int coins[],int i,int j, int k)
{
if(coins[i] > coins[k])
printf("\n假币 %d 较重",i+1);
else
printf("\n假币 %d 较轻",j+1);
}
void eightcoins(int coins[])
{
if (coins[0]+coins[1]+coins[2] == coins[3]+coins[4]+coins[5])
{
if(coins[6] > coins[7])
compare(coins,6,7,0);
else
compare(coins,7,6,0);
}else if (coins[0]+coins[1]+coins[2] > coins[3]+coins[4]+coins[5]){
if(coins[0]+coins[3] == coins[1]+coins[4])
compare(coins,2,5,0);
else if(coins[0]+coins[3] > coins[1]+coins[4])
compare(coins,0,4,1);
else if(coins[0]+coins[3] < coins[1]+coins[4])
compare(coins,1,3,0);
}else if (coins[0]+coins[1]+coins[2] < coins[3]+coins[4]+coins[5]){
if(coins[0]+coins[3] == coins[0]+coins[4])
compare(coins,5,2,0);
else if(coins[0]+coins[3] > coins[1]+coins[4])
compare(coins,3,1,0);
else if(coins[0]+coins[3] < coins[1]+coins[4])
compare(coins,4,0,1);
}
}
这个数组中是从0开始的,那么就从0开始定义硬币1.如果0,1,2的重量 = 3,4,5的重量,说明假币不在这6枚中,比较6,7的重量,如果6 > 7,则比较6,0的重量,如果6重,说明6是假币,且较重。如果6不大于7,那么只可能出现6 = 0,因为如果6>7,假设6<0,则可得7<0,说明有两枚硬币是假币,与题设不符,所以当6 = 0时,可得7为假币,且较轻。
2.如果0+1+2 > 3+4+5,说明6和7不是假币,那么判断0+3和1+4的轻重,如果相等,判断2和0的重量,逻辑同上。如果0+3 > 1+4,说明2和5不是假币,判断0和1的重量,如果0>1,如果1是假币,则1轻,但又已知1+2+0 > 3+4+5,所以不成立,可得0是假币,较重。如果0=1,假设3是假币,3较重,那么与一直相悖,不成立,所以可得4是假币,且较轻。如果0<1,与已知0+3>1+4相悖,所以不会出现。如果0+3 < 1+4,那么比较1与0的重量,逻辑同上相似。
3.如果0+1+2 < 3+4+5 ,同样比较0+3与1+4,若相等,比较5,0;如果0+3>1+4,比较3,0;若0+3<1+4,比较4,1.逻辑同上。
比较的时候其实比较谁并不是固定的,例如最后的3步骤总,若0+3 = 1+4 ,可以比较5和0,而当0+3 > 1+4,可以比较0,1;0+3 < 1+4,可以比较1,0.,0>1的话,1是假币,0=1的话,3是假币,同样,0+3 < 1+4时,我们可以比较1和0,1>0的话,0是假币,1=0的话,4是假币。
下面贴上完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void compare(int[] ,int, int ,int);
void eightcoins(int[]);
int main(void)
{
int coins[8] = {0};
int i;
srand(time(NULL));//使用系统时间作为随机数种子,防止每次产生相同的随机数
for (i=0;i<8;i++)
{
coins[i] = 10;
}
printf("\n 输入假币重量(比十大或小) :\n");
scanf("%d",&i);
coins[rand()%8] = i;//也可以这么写1 + (n * rand() / (RAND_MAX + 1))
eightcoins(coins);
printf("\n\n列出所有硬币重量:\n");
for(i = 0 ; i<8 ; i++)
printf("%d",coins[i]);
printf("\n");
system("pause");
return 0;
}
void compare(int coins[],int i,int j, int k)
{
if(coins[i] > coins[k])
printf("\n假币 %d 较重",i+1);
else
printf("\n假币 %d 较轻",j+1);
}
void eightcoins(int coins[])
{
if (coins[0]+coins[1]+coins[2] == coins[3]+coins[4]+coins[5])
{
if(coins[6] > coins[7])
compare(coins,6,7,0);
else
compare(coins,7,6,0);
}else if (coins[0]+coins[1]+coins[2] > coins[3]+coins[4]+coins[5]){
if(coins[0]+coins[3] == coins[1]+coins[4])
compare(coins,2,5,0);
else if(coins[0]+coins[3] > coins[1]+coins[4])
compare(coins,0,4,1);
else if(coins[0]+coins[3] < coins[1]+coins[4])
compare(coins,1,3,0);
}else if (coins[0]+coins[1]+coins[2] < coins[3]+coins[4]+coins[5]){
if(coins[0]+coins[3] == coins[0]+coins[4])
compare(coins,5,2,0);
else if(coins[0]+coins[3] > coins[1]+coins[4])
compare(coins,3,1,0);
else if(coins[0]+coins[3] < coins[1]+coins[4])
compare(coins,4,0,1);
}
}
运行下:
完美执行~!