C++算法——查找假币问题:

编写一个实验程序查找假币问题。有n(n>3)个硬币,其中有一个假币,且假币较轻,采用天平称重方式找到这个假币,并给出操作步骤。

本题采用的是分治法求解问题,因为所有的硬币里面必定有一个是假币,而且假币质量轻,
当硬币是奇数个数时,如果左右两边一样重,那么假币必定是中间那个,直接返回就可以了,
否则就去左右两边找假币,那边轻就去那边找假币,如果硬币是偶数个数时,就不会存在左
右两边相等,直接判定左右两边那边轻就可以了,那边轻就去哪边调用函数递归,知道左由
两边下标相差一或相等即可找到假币。

代码实现:

#include
using namespace std;
#define N 1000
int SUM(int weight[], int m, int n)//求重量和
{
    int sum = 0;
    for (int i = m; i <= n; i++)
    {
        sum += weight[i];
    }
    return sum;
}
int find(int weight[], int left, int right)
{
    if (right - left == 1)//先判定再递归
        return weight[right] > weight[left] ? left : right;
    if (right == left)
        return right;
    int mid = (right + left) / 2;
    if ((right - left) % 2 == 0)//硬币数量为奇数个数时
    {
        int lw = SUM(weight, left, mid - 1);
        int rw = SUM(weight, mid + 1, right);
        if (lw == rw)
            return mid;
        lw > rw ? find(weight, mid + 1, right) : find(weight, left, mid - 1);
    }
    else if ((right - left) % 2 == 1)//硬币为偶数个数时
    {
        int lw = SUM(weight, left, mid);
        int rw = SUM(weight, mid + 1, right);
        lw > rw ? find(weight, mid + 1, right) : find(weight, left, mid);
    }
}
int main()
{
    int n;
    int weight[N] = { 0 };
    cout << "请输出硬币的个数:>\n";
    cin >> n;
    cout << "请输出各个硬币的重量:>\n";
    for (int i = 0; i < n; i++)
    {
        cout << "第" << i+1 << "个硬币的重量是:>";
        cin >> weight[i];
    }
    int sz = find(weight, 0, n - 1);
    cout << "第" << sz + 1 << "个是假币!\n";
    return 0;
}
注意:1.硬币为奇偶个数时一定要分情况讨论,头脑清晰,明确左右区间

2.递归调用前先判定,这样方便找到递归函数的出口,不至于后面混淆

你可能感兴趣的:(c++,算法)