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

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

#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;
}