[算法课]硬币称重 原创
题目来源:网络
算法标签:分治策略
关于硬币:关于一个硬币的问题。
如果有16个硬币,都是一元的 重量是6g,其中有1个是假硬币重量是5g,要求找出假的那个?
模仿实现 :
(1)需要一个数组 int a[17];
(2)所有数组一开始全部给初始值6
(3)利用随机函数 生成标号i 范围在1-16之间 a[i]=5
(4)利用分治法方法 来解决问题
思路
首先考虑的是折半查找,但是这样操作必须要解决的是需要排序为前提,而排序就违背了题目本意。
其次从归并考虑,发现想从逆序对处理,返现递归到底合并时候又难计算总的位次,
于是我们从特性入手,
因为5是奇数,所以二分两边的块是否%2!=0,否就二分检索另一块
我们把数组设置为a1到a17,这样中间数就是1+17>>1=9,初次只计算1-8和10-17,以此类推所有的递归都不重不漏。
这样只要检测到mid是奇数,返回即可
注明:
难点感觉完全是边界值处理
题目代码
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int a[18];
int search(int l, int r)
{
int mid = l + r >> 1;
if (a[mid] & 1)return mid;
int p1 = 0, p2 = 0;
for (int i = l; i < mid; i++)p1 += a[i];
for (int i = mid + 1; i <= r; i++)p2 += a[i];
if (p1 & 1)search(l, mid);
else search(mid + 1, r);
}
int main()
{
for (int i = 1; i < 18; i++)a[i] = 6;
srand(time(NULL));
a[rand() % 17 + 1] = 5;
cout << search(1, 17);
return 0;
}