Codeforces 1213D Equalizing by Division

cf題面函數

中文題意

給n個數,每次能夠把其中一個數字位運算右移一位(即整除以二),問要至少操做幾回才能讓這n個數中有至少k個相等。spa

解題思路

這題還有個數據範圍更小的簡單版本,n和k是50,\(a_i\)仍是2e5。.net

發現\(1\leqslant a_i\leqslant 2⋅10^5\),這些數字除以二隻會變小,換句話說,整個過程當中數字大小都不會超過\(2⋅10^5\),而後就能夠用相似桶排序的方法,把全部數字不停除以二,把獲得一個數字所用的步驟數(包括0步,即原數字)扔到相應的桶裏,以後統計每一個桶,有沒有k個數,若是有,就計算其中最小的k個步驟數之和,用於更新答案。(感受這段話還不如代碼好懂)code

這種思惟題,標籤都很差打,就模仿cf,給這題打個「暴力」的標籤算了排序

源代碼

#include<vector>
#include<cstdio>
#include<algorithm>
const int MAXN=2e5+5;
int n,k,mxa;
std::vector<int> t[MAXN];//t[i]表示達到i的操做次數
int main()
{
    scanf("%d%d",&n,&k);
    while(n--)
    {
        int a;
        scanf("%d",&a);
        mxa=std::max(mxa,a);
        int cur=0;
        while(a)
        {
            t[a].push_back(cur);
            cur++;
            a>>=1;
        }
        t[0].push_back(cur);
    }
    int ans=0x7fffffff;
    for(int i=0;i<=mxa;i++)
    {
        if(t[i].size()<k) continue;
        std::sort(t[i].begin(),t[i].end());
        int sum=0;
        for(int j=0;j<k;j++) sum+=t[i][j];//題解標程使用了accumulate函數
        ans=std::min(ans,sum);
    }
    printf("%d\n",ans);
    return 0;
}
相關文章
相關標籤/搜索