算法学习笔记6——减治法求解假币问题

描述:
在n枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较两组硬币,设计一个高效的减治算法来检测出这枚假币。
int nCoin(int coin[], int n, int p, int q);
coin[]数组存储各枚硬币的重量。
算法分析:
将硬币分成三组,前两组有[n/3]枚硬币A和B,其余的硬币作为第三组C,将前两组硬币放入天平比较。如果他们的重量相同,那么假币一定在第三组C中,用同样的方法对第三组C进行处理;如果前两组的重量不相等,那假币就出现在和(C/(n-[n/3]*2)*n/3重量不相等的一组里,重复上述过程直至找到假币。
完整代码:

#include <iostream> 
#include <stdlib.h>
using namespace std;
void create(int coin[],int n)
{
	for(int i=0;i<n;i++){
		coin[i]=1;
	}
	int x=rand()%n;
	coin[x]=2;
	for(int i=0;i<n;i++){
		cout<<coin[i]<<" ";
	}
	cout<<endl;
} 

int nCoin(int coin[],int n,int p,int q)
{
	int n1,n2,n3,w1=0,w2=0;
	if(n==1){
		return p+2;
	}
	if(n%3==0)
        n1=n2=n3=n/3;
    else
    {
        n1=n2=n/3+1;
        n3=n-n1-n2;
    }
	for(int i=0;i<n1;i++){
		w1+=coin[p+i];
	} 
	for(int i=n1;i<n1+n2;i++){
		w2+=coin[p+i];
	}
	if(w1==w2){
		return nCoin(coin,n3,p+n1+n2,q);
	}else{
		int w=coin[q-1];
		if(w1!=w*n1){
			return nCoin(coin,n1,p,p+n1);
		}else{
			return nCoin(coin,n2,p+n1,p+n1+n2);
		}
	}
}
int main()
{
	int n;
	cout<<"输入硬币的总个数"<<endl;
	cin>>n;
	int coin[n];
	create(coin,n);
	cout<<"假币是第"<<nCoin(coin,n,0,n)<<"枚"<<endl; 
	return 0;
}

运行结果:
算法学习笔记6——减治法求解假币问题_第1张图片

你可能感兴趣的:(算法学习笔记6——减治法求解假币问题)