問題定義:已知N枚硬幣質量,其中有一枚假幣(或輕或重),請找出假幣
思路:
- 若N<3,無法判斷
- 若範圍縮小至一枚硬幣,拿一枚真幣比較輕重
- 若範圍縮小至兩枚硬幣,拿一枚真幣與其中一枚比較輕重,縮小範圍至一枚硬幣
- 若範圍在三枚以上,將硬幣三分,左邊num/3枚,右邊num/3枚,其餘放中間(num爲範圍大小)。
4.1若左邊硬幣質量等於右邊,縮小範圍到中間
4.2若左邊硬幣質量等於num/3枚真幣的質量,縮小範圍到右邊
4.2.1 若不等於,假幣範圍在左邊
代碼加註釋:
#include<iostream>
#include<cstdlib>
using namespace std;
#define N 1005
void Judge(int *a,int n,int p,int q)
{
if(n<3)
{
cout<<"無法判斷"<<endl;
return ;
}
if(p==q)//範圍縮小到一枚硬幣
{
if(p>0)
{
if(a[p]>a[0])
{
cout<<"假幣序號爲"<<p+1<<",假幣重量爲"<<a[p]<<",且假幣較重!"<<endl;
}
else
cout<<"假幣序號爲"<<p+1<<",假幣重量爲"<<a[p]<<",且假幣較輕!"<<endl;
}
else
{
if(a[p]>a[n-1])
{
cout<<"假幣序號爲"<<p+1<<",假幣重量爲"<<a[p]<<",且假幣較重!"<<endl;
}
else
cout<<"假幣序號爲"<<p+1<<",假幣重量爲"<<a[p]<<",且假幣較輕!"<<endl;
}
}
else if(q-p==1)//範圍縮小到兩枚硬幣
{
if(p>0)
{
if(a[p]==a[0]) Judge(a,n,p+1,q);
else Judge(a,n,p,q-1);
}
else if(q<n-1)
{
if(a[p]==a[n-1]) Judge(a,n,p+1,q);
else Judge(a,n,p,q-1);
}
}
else if(p<q)//範圍在三枚硬幣以上
{
int temp=(q-p+1)/3;
int sum1=0,sum2=0;
for(int i=0;i<temp;i++)
{
sum1+=a[p+i];
sum2+=a[q-i];
}
if(sum1==sum2)
{
Judge(a,n,p+temp,q-temp);
}
else
{
if(sum1==a[p+temp]*temp)
{
Judge(a,n,q-temp+1,q);
}
else
{
Judge(a,n,p,p+temp-1);
}
}
}
}
int main()
{
int a[N],n;
cout<<"請輸入硬幣枚數:";
cin>>n;
cout<<"請輸入硬幣質量:";
for(int i=0;i<n;i++)
cin>>a[i];
Judge(a,n,0,n-1);
return 0;
}
截圖: