悪いコインを探す

問題の説明

n(n> = 3)のコインの中に、不適格なコイン(軽すぎるまたは重すぎる)があります。計量に使用できる天びんが1つだけで、計量するコインの数に制限がない場合は、アルゴリズムを設計して、この不適格なコインを取り出して、計量の数を最小限にします(O(n)よりも良い)。

(ヒント:n / 3またはn / 4に分割し、少なくとも2つは同じ量にします)

アイデア

二分法のアイデアを利用して、それは3つの山に分割され、そのうちの2つは同じ数であり、もう1つは一貫性がない可能性があります。コインの数が奇数か偶数かに関係なく、(3で割るのが最適です)ほぼ同じ3つのパイルに分割できます。2つのパイルが同じである場合は比較します。等しくない場合、不良コインは2つのパイルにあります。それらが等しい場合、それらは3番目の山にあります。コインが2つになるまで、この操作を繰り返します。

 

//Q6   在n(n>=3)枚硬币中有一枚重量不合格的硬币(过轻或过重),如果只有一架天平可以用来称重且称重的硬币数没有限制,
// 设计一个算法,找出这枚不合格的硬币,使得称重的次数最少(优于O(n))。

// 思路: 采用分治策略。如果n<3,那么将拿走的硬币与剩下的硬币比较,不等的是坏币;将n枚硬币分为大致相等的3份,
//如果n(mod 3)≠0,那么令两份少的硬币相等。取两份相等的硬币放到天平上,如果不等,那么这两份硬币中含有坏币,
//否则坏币在第3份中。递归处理,直到n<3为止。

//关键词:硬币 坏 分治coins

//硬币结构体
struct Coin
{
    int weight;
    int label;
    Coin(int weight, int label)// 构造函数
    {
        this->weight = weight;
        this->label = label;
    }
};

int gettotalweight(vector<Coin> coins) {
    int totalweight = 0;
    for (vector<Coin>::iterator iter = coins.begin(); iter != coins.end(); ++iter) {
        totalweight = totalweight+iter->weight;
    }
    return totalweight;
}

#include "algorithm"
int turewight = 0;
int findBadCoin(vector<Coin> coins) {
    int n = coins.size();
    int k = n / 3; // 将硬币分为3堆 个数分别为k,k,n-2k
    vector<Coin> A,B,C;  
    int result = 0;
    A.insert(A.begin(),coins.begin() , coins.begin() + k);
    B.insert(B.begin(),coins.begin() + k, coins.begin() + 2*k );
    C.insert(C.begin(),coins.begin() + 2*k, coins.end());
    if (n == 2)
    {
        coins[0].weight == turewight ? result = coins[1].label : result = coins[0].label;
        return result;
    }
    if(n>3){
        if (gettotalweight(A)!= gettotalweight(B)) { //A与B的重量不相等
            coins.clear();
            coins.insert(coins.begin(), A.begin(), A.end()); // 重新整合A和B的元素到coins中
            coins.insert(coins.end(), B.begin(), B.end());
            turewight = C[0].weight;//记录真实重量方便最后的比较
        }
        else // 坏币在第3堆中
        {
            coins.clear();
            coins.insert(coins.begin(), C.begin(), C.end());
        }      
        return findBadCoin(coins);
    }  
}
//Ques20201004
int main()
{
    //Q1
    //cin >> k;//输入要找的数字c语言把cin换为scanf即可
    //cout << BinarySearch(0, 9);//从数组a[0]到a[9]c语言把cout换为printf即可

    //Q2
    /*int n = 9;
    int arr[] = { -1,3,5,2,7,8,-9,1,-4 };
    
    f(arr,n);*/


    // Q3
 /*   char A = 'A';
    char B = 'B';
    char C = 'C';
    Hanoi(3, A, B, C);*/



    //Q4
   /* int arr[] = { 1,3,5,8,9,7,6,1,2 };
    cout<<siglePeak(arr,0,8);*/


    // Q5
    //int arr[] = { 1,1,2,3,5,7,8,9 };
    //printL_U(arr,1,7,8);// L=1,U=7 数组长度为8

    // Q6
    vector<Coin> coins;
    for (int i = 0; i < 19;i++) {
        
        if (i == 12) {// 坏硬币的重量为2           
            coins.push_back(Coin(2, 12));
        }
        else { // 生成20个硬币
            coins.push_back(Coin(1, i));
        }
    }
    cout<<findBadCoin(coins);
    return 0;
}

 

おすすめ

転載: blog.csdn.net/Toky_min/article/details/108923527