实验四——减治法求解假币问题

n枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较两组硬币,设计一个高效的减治算法来检测出这枚假币。

提示:将硬币分成ABC三组,如果A等于C,则假币在B组,递归将B三等分,重复上述步骤;如果A不等于C,则假币在AC中,分别将ABCB比较,哪个不等于B,则假币必在其中,递归将其三等分,重复上述步骤。注意,当分组里的硬币数少于3个时,无须划分,直接将组里某个硬币与组外任一硬币比较,不同即是假币,相同的话说明另外一个必是假币。

#include <iostream>
using namespace std;

#define numnum  9

int coin[numnum] = {2,2,2,2,2,2,2,2,4};


int Number_Sum(int arr[],int low,int high)
{
	int sum = 0;
	for(int i = low;i<=high;i++)
		sum += arr[i];
	return sum;
}

int nCoin(int coin[], int n, int low, int high)
{
	int k = n/3;
	int Remain = n%3;

	if(Remain == 0)                                         ////余数为零的情况!
	{
		int index = 0;
		int A,B,C;
		A = Number_Sum(coin,low,low+k-1);
		B = Number_Sum(coin,low+k,low+2*k-1);
		C = Number_Sum(coin,low+2*k,high);

		//cout<<A<<B<<C<<endl;

		if(n == 3)
		{
			if(A==B)
				index = high;
			if(A==C)
				index = high-1;
			if(B==C)
				index = low;
			return index;
		}
		else{
		if(A==B)
		{
			cout<<"reamian0 aaaaabbbbb"<<endl;  
				index = nCoin(coin,k,low+2*k,high);
			return index;
		}
		if(A==C)
		{
			cout<<"reamian0 aaaaaccccc"<<endl;
			index = nCoin(coin,k,low+k,low+2*k-1);
			return index;
		}
		if(B==C)
		{
			cout<<"reamian0 bbbbbcccc"<<endl;
		    index = nCoin(coin,k,low,k-1);
			return index;
		}
		}
	}


	if(Remain == 1)                                          ////余数为1的情况!
	{
		//把最后一个去掉,比较。
	   int index = high;
		int A,B,C;

		if(n==1)
			return index;

		else{
		A = Number_Sum(coin,low,low+k-1);
		B = Number_Sum(coin,low+k,low+2*k-1);
		C = Number_Sum(coin,low+2*k,high-1);

		//cout<<A<<B<<C<<endl;

		if(A == B && B == C){
			return index;
		}
		else if(A==B)
		{
			cout<<"ramain1 aaaabbb"<<endl;                                  
			index = nCoin(coin,k,low+2*k,high-1);
			return index;
		}
		else if(A==C)
		{
			cout<<"ramain1 aaaaccc"<<endl;   
			index = nCoin(coin,k,low+k,low+2*k-1);
			return index;
		}
		else if(B==C)
		{
			cout<<"ramain1 bbbccc"<<endl;   
			index = nCoin(coin,k,low,k-1);
			return index;
		}
	}
}

	if(Remain == 2)                                        ////余数为2的情况!
	{
	   int index = 0;
	   int index1 = high-1;
	   int index2 = high;
		int A,B,C;
		A = Number_Sum(coin,low,low+k-1);
		B = Number_Sum(coin,low+k,low+2*k-1);
		C = Number_Sum(coin,low+2*k,high-2);
		//cout<<A<<B<<C<<endl;
		if(n<3)
		{
			int campare11 ;
			if(high != numnum-1)
				campare11 = coin[numnum-1];
			else 
				campare11 = coin[0];
			if(coin[high] == campare11)
				index = low;
			if(coin[low] == campare11)
				index = high;
			return index;
		}

		else{
		if(A==B&&B==C)
		{
			int cam = coin[0];
			if(coin[high-1] == cam)
					index = index2;
			if(coin[high] == cam)
					index = index1;
			return index;
		}
		else if(A==B)
		{     
			cout<<"ramain2 aaaabbb"<<endl;   
			index = nCoin(coin,k,low+2*k,high-2);
			return index;
		}
		else if(A==C)
		{	
			cout<<"ramain2 aaaacccc"<<endl;   
		    index = nCoin(coin,k,low+k,low+2*k-1);
			return index;
		}
		else if(B==C)
		{
			cout<<"ramain2 bbbccc"<<endl;   
			index = nCoin(coin,k,low,k-1);
			return index;
		}
		}
	}
	}

int main()
{
	int number;
	if(numnum<3){
		cout<<"数量太少,无法比较"<<endl;
		return 0;
	}
	number  = nCoin(coin, numnum, 0, numnum-1);
	int campareble;
	if(number!= numnum-1)
		campareble = coin[numnum-1];
	else 
		campareble = coin[0];
	if(coin[number] < campareble)
		cout<<"假币的位置为 "<<number<<"  并且假币偏轻"<<endl;
	else
		cout<<"假币的位置为 "<<number<<"  并且假币偏重"<<endl;
	return 0;
}


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页