TopCoder SRM 616 DIV1 ColorfulCoins TopCoder - 13061

题面

题意

有n种硬币,每种硬币的颜色不同,你想要知道每种硬币的颜色,而且你不知道一共有哪些颜色。
你知道硬币的币值,而且任意两个硬币的币值都有倍数关系。
你可以向一个取款机取任意金额,它会给你最少的硬币数量,问你至少要取几次钱才能知道每种硬币的颜色。

做法

首先要找到最优的查找方案。
要想去区分两种硬币,只能通过硬币的数量,因为可以取多次,所以每次取某种硬币的数量可以不同。对于某种硬币,我们可以通过比较几次取它的数量所构成的序列(除了0,0,0,0……)来确定它的种类。因此,如果每种硬币(除了币值最大的硬币)与比它币值大的硬币的最小币值比都为d的话,取n次最多可以辨别出d^n-1种硬币,之后的事情就简单了。

代码

#include <bits/stdc++.h>
#define ll long long
#define P pair<ll,ll>
#define mp make_pair
#define fi first
#define se second
#define N 110
using namespace std;

class ColorfulCoins
{
    public:
        int minQueries( vector<long long> values );
};

inline int ask(ll u,ll v)
{
    int res=0;
    ll t=1;
    for(;t<=v;t*=u) res++;
    return res;
}

int ColorfulCoins::minQueries(vector<long long> values)
{
    ll n=values.size()-1,t,sum=0,i;
    int need=1;
    map<ll,ll>cnt;
    map<ll,ll>::iterator it;
    vector<P>use;
    cnt.clear();
    use.clear();
    for(i=0; i<n; i++)
    {
        t=values[i+1]/values[i];
        if(!cnt.count(t)) cnt[t]=1;
        else cnt[t]++;
    }
    for(it=cnt.begin(); it!=cnt.end(); it++)
    {
        sum+=(*it).se;
        need=max(need,ask((*it).fi,sum));
    }
    return need;
}

猜你喜欢

转载自blog.csdn.net/yzyyylx/article/details/81015312