//给定n个一模一样的小球,只有一个是次品球,次品球的重量可能比其他球大或小,通过用中间球的重量
//和两端球重量比及划分区间的方法可以确定次品球,如果用称重的方法有错误,如球:1 1 1 1 2
//划分区间后是(1 1 1) (1 2)则两区间重量相等
#include<iostream>
#include<stdlib.h>
using namespace std;
const int Max=1e8;
void SearchGoal(int a[],int n,int l,int h,bool &find,int& e)
{
if(n<=2 || n>=Max) //球的个数应该大于2
{
cerr<<"参数错误,球的个数太少或太多!"<<endl;
return;
}
if(l<h)
{
static int s;
int mid;
mid=(l+h)/2;
if(a[mid]==a[l] && a[mid]==a[h]) //中间和两端球重量相等,则标准重量s确定
{
s=a[mid];
}
else
{
find=true; //找到次品球,find为真
if(l+1==h) //划分区间是l==mid,l+1==h
{
if(s) //找到标准重量,用s找出次品球
{
if(a[l]==s) e=a[h];
else if(a[h]==s) e=a[l];
else
{
cerr<<"至少有两个次品球,输入错误!"<<endl;
exit(1);
}
}
}
else //区间是[l,mid,h]
{
if(a[mid]==a[l] && a[mid]!=a[h])
{
e=a[h];
}
else if(a[mid]==a[h] && a[mid]!=a[l])
{
e=a[l];
}
else if(a[l]==a[h] && a[mid]!=a[l])
{
e=a[mid];
}
else
{
cerr<<"至少有两个次品球,输入错误!"<<endl;
exit(1);
}
}
}
if(!find) //未发现次品球,左右区间递归处理
{
SearchGoal(a,n,l,mid-1,find,e);
SearchGoal(a,n,mid+1,h,find,e);
}
}
}
void main()
{
int n,e;
int *a;
bool find=false;
cout<<"输入球的个数:";
cin>>n;
a=new int[n];
int i;
for(i=0;i<n;i++)
{
cout<<"输入第"<<i<<"个小球的重量:";
cin>>a[i];
}
SearchGoal(a,n,0,n-1,find,e);
cout<<"次品球的重量是:"<<e<<endl;
}