从算法学起C语言--八枚硬币

来源:互联网 发布:w3cschool java 编辑:程序博客网 时间:2024/05/22 15:15

转载请注明出处,谢谢~

背景说明:

现有八枚硬币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);elseprintf("\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);elsecompare(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);elseprintf("\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);elsecompare(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
原创粉丝点击