问题 A: 找出伪币
题目描述
给你一个装有n枚硬币的袋子。n枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这枚伪造的硬币.
输入
测试数据有多行,第一行是金币的数量n(n为正整数,并且n<=5000000);接下来一行是n枚硬币的重量,用空格隔开。
输出
输出假币的位置及重量,用空格隔开。
样例输入
4
43 43 43 1
样例输出
4 1
代码
#include <iostream>
using namespace std;
// 分两边
// 为偶数时分两边,轻的一边 有问题
// 奇数时 中间保留一位 如果左右相等 中间伪币,
// 否则重复偶数步骤
int findByCoins(int *coins, int left,int right){
if(left+1==right){
if (coins[left] > coins[right])
return right;
else
return left;
}
int i,mid,isOdd,wL=0,wR=0;
mid =left + (right - left)/2;
isOdd = (right - left+1)%2;
if(isOdd==0){
for(i=left;i<=mid;i++){ // 1 2 3 4 5 6 7 8
wL += coins[i];
}
for(i=mid+1;i<=right;i++){ // 1 2 3 4 5 6
wR += coins[i];
}
if(wL < wR)
return findByCoins(coins,left,mid);
else if(wL > wR)
return findByCoins(coins,mid+1,right);
}else{
for(i=left;i < mid;i++) // 5 5 5 5 5 2 5 5 5 5 5
wL += coins[i];
for(i=mid+1;i<=right;i++)
wR += coins[i];
if(wL < wR)
return findByCoins(coins,left,mid-1);
else if(wL > wR)
return findByCoins(coins,mid+1,right);
else
return mid;
}
}
int main(int argc, char** argv) {
int n;
cin >> n;
int *coins = new int[n];
for(int i=0;i<n;i++){
cin >> coins[i];
}
int left,right,mid;
left=0;
right=n-1;
int idx = findByCoins(coins,left,right);
cout<<idx+1<<" "<<coins[idx]<<endl;
return 0;
}