zoukankan      html  css  js  c++  java
  • 寻找假币

    一、问题描述

    一个袋子里有若干硬币,其中一枚是假币,并且和假币和真币一模一样,目前只知道假币比真币轻一点。请问如何找到这枚假币?

    二、算法分析

    根据分治的策略,将硬币平分为两份(奇数个硬币取出中间的硬币后再平分),比较两边的重量之和的大小。左侧重,则假币在右半段,反之,假币在左半段(或者中间的假币),然后继续在有假币的半区查找,直到剩余两个硬币,比较大小后,返回假币的位置。


    时间复杂度:O(logn)。

    三、代码实现

    #include <stdio.h>
    
    #define MAXNUM 30
    
    int FalseCoin(int coin[], int low, int high)
    {
        // 两个硬币的比较
        if (low + 1 == high) {
            if (coin[low] < coin[high]) {
                return low + 1;
            }
            return high + 1;
        }
        
        int sum1 = 0, sum2 = 0, sum3 = 0;
        int mid = (low + high) >> 1;
        int i;
        
        // 偶数个硬币
        if ((high - low + 1) % 2 == 0 ) {
            
            // 左半段
            for (i = low; i <= mid; i++) {
                sum1 += coin[i];
            }
            // 右半段
            for (i = mid + 1; i <= high; i++) {
                sum2 += coin[i];
            }
            
            // 左侧重,则假币在右半段
            if (sum1 > sum2) {
                return FalseCoin(coin, mid + 1, high);;
            }
            // 右侧重,则假币在左半段
            else if (sum2 > sum1){
                return FalseCoin(coin, low, mid);;
            }
            else {
                printf("没有假币。输入的硬币重量有误!");
            }
        }
        // 奇数个硬币
        else {
            // 左半段,除去中间的一个硬币
            for (i = low; i <= mid - 1; i++) {
                sum1 += coin[i];
            }
            // 右半段,除去中间的一个硬币
            for (int i = mid + 1; i <= high; i++) {
                sum2 += coin[i];
            }
            
            sum3 = coin[mid];
            
            // 左侧重,则假币在右半段
            if (sum1 > sum2) {
                return FalseCoin(coin, mid + 1, high);
            }
            // 右侧重,则假币在左半段
            else if (sum2 > sum1){
                return FalseCoin(coin, low, mid - 1);
            }
            else {
                // 中间的是假币
                if (coin[mid] != coin[low]) {
                    return mid + 1;
                }
                else {
                    printf("没有假币。输入的硬币重量有误!");
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        int coin[] = { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 };
    
        int position = FalseCoin(coin, 0, 9);
        
        printf("假币在第 %d 个位置", position);
    
        return 0;
    }
    
    假币在第 4 个位置
    
  • 相关阅读:
    I/O模型
    同步异步与协程
    GIL(全局解释器锁)
    解决pycharm启动慢
    操作系统发展史
    TCP和UDP
    粘包问题
    网络编程
    异常
    常用函数汇总
  • 原文地址:https://www.cnblogs.com/dins/p/looking-for-counterfeit.html
Copyright © 2011-2022 走看看