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

转载请注明出处,谢谢~

背景说明:

现有八枚硬币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);
	}
}

运行下:


完美执行~!


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值