程序基本算法习题解析 用分治法设计一个算法,找出伪造硬币

题目:

 一个装有16枚硬币的袋子,16枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻。现有一台可用来比较两组硬币重量的仪器,请使用分治法设计一个算法,可以找出那枚伪造的硬币。

首先建立一个有16个int数据类型的数组,模拟16枚硬币,真币赋为1,假币赋为0。根据二分搜索法的原理,设计算法代码如下:

// Chapter7_3.cpp : Defines the entry point for the application.
// 用分治法设计一个算法,找出伪造硬币
// 一个装有16枚硬币的袋子,16枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻。
// 现有一台可用来比较两组硬币重量的仪器,请使用分治法设计一个算法,可以找出那枚伪造的硬币。
 
#include "stdafx.h"
#include<iostream>
using namespace std;

const int total = 16; //硬币总数
int calltimes = 0; //查找次数
//求重量和
int weight(int arr[], int Begin, int End)
{
	int sum = 0;
	for(int i=Begin; i<=End;i++)
		sum += arr[i];
	return sum;
}
//找假币
int findFake(int arr[], int Begin, int End)
{
	calltimes++;
	cout << "第 " << calltimes << " 次查找" << endl;
	//如果最后二分到只有两个数时
	if(End-Begin == 1)
	{
		if(arr[Begin] >= arr[End]) //硬币在后半部分
			return End;
		else
			return Begin;
	}
	else
	{
		if(weight(arr,Begin,(Begin+End)/2) > weight(arr,(Begin+End)/2+1,End)) //硬币在后半部分
		{
			Begin = (Begin+End)/2+1;
			cout << "银币在后半部分" << endl;
		}
		else
		{
			End = (Begin+End)/2;
			cout << "银币在前半部分" << endl;
		}
		return findFake(arr, Begin, End);
	}

}
int main()
{
	int coin[total],fake;
	//模拟硬币真伪,1为真硬币,0为假硬币
	for(int i=0;i<total;i++)
		coin[i] = 1;
	coin[3] = 0;  //假设第四枚硬币为假
	fake = findFake(coin, 0, total-1)+1;
	cout << "the fake coin is number " << fake << endl;
	system("pause");
	return 0;
}

其中,

coin[3] = 0;  //假设第四枚硬币为假

是假定某个元素为假币,这里是假设第4枚是假币(数组角标从0开始)。

运行结果如下:

将假币换成第9个试试,即

coin[8] = 0;  //假设第九枚硬币为假

运行结果如下:

猜你喜欢

转载自blog.csdn.net/elma_tww/article/details/85048831