CodeForces-916B-ジェイミーと(ラウンド後に変更)バイナリシーケンス(构造)

リンク:

https://vjudge.net/problem/CodeForces-916B

質問の意味:

ジェイミーはCodeforcesラウンドを準備しています。彼は問題のためにアイデアを持っているが、それを解決する方法を知りません。彼は次のような問題の解決策を書くのに役立ちます。

各番号の電源への2つの和が数nに等しく、回答最大の整数ができるだけ小さくなるように、k個の整数を見つけます。複数回答があるかもしれないとして、あなたは出力に辞書的に最大のものを求められます。

より明確にするために、長さk(A1、A2、...、AK)として、すべての整数列を考えます。各シーケンスに値を与えます。辞書最大で、出力は1最小のy値を持つすべての配列(単数または複数)のうち。

力と辞書順の定義についてはノートを参照してください。

アイデア:

最初にこの時間長がmより大きければ、それは可能でない、配列の最小数を構成している。
そうでなければ、より大きなフロント優先決意はすべて費やし、または小開始する減算することができません。

コード:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#include <iomanip>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;

LL n, m;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    multiset<int> st;
    for (int i = 63;i >= 0;i--)
    {
        if ((1ULL<<i) <= n)
        {
            st.insert(i);
            n -= (1LL<<i);
        }
    }
    if (st.size() > m)
        puts("No");
    else
    {
        while (st.size() < m)
        {
            if (st.size() == 1)
            {
                int t = *st.rbegin();
                st.erase(*st.rbegin());
                st.insert(t-1);
                st.insert(t-1);
            }
            else
            {
                int cnt = st.count(*st.rbegin());
                if (m-st.size() >= cnt)
                {
                    int t = *st.rbegin();
                    st.erase(t);
                    for (int i = 1;i <= cnt*2;i++)
                        st.insert(t-1);
                }
                else
                {
                    int t = *st.begin();
                    t--;
                    st.erase(st.begin());
                    while (st.size()+2 < m)
                    {
                        st.insert(t);
                        t--;
                    }
                    st.insert(t);
                    st.insert(t);
                }
            }
        }
        cout << "Yes" << endl;
        for (multiset<int>::reverse_iterator it = st.rbegin();it != st.rend();++it)
            cout << *it << ' ';
        cout << endl;
    }

    return 0;
}

おすすめ

転載: www.cnblogs.com/YDDDD/p/11391963.html