1. 程式人生 > >程式基本演算法習題解析 用分治法設計一個演算法,找出偽造硬幣

程式基本演算法習題解析 用分治法設計一個演算法,找出偽造硬幣

題目:

 一個裝有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;  //假設第九枚硬幣為假

執行結果如下: