码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #638 (Div. 2)

时间:2020-05-02 10:10:41      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:return   str   题解   back   names   数列   进制   oid   set   

比赛链接:https://codeforces.com/contest/1348

A - Phoenix and Balance

题意

将长为偶数的等比数列 $2^1, 2^2, 2^3, ... , 2^n$ 分为两个长为 $\frac{n}{2}$,相差最小的子序列。

题解

原序列可以看做一个二进制数,比如当 $n = 6$ 时:

原序列可以看做:$111111$

相差最小的分法为:

$100011$

$011100$

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n; cin >> n;
    long long a = 0, b = 0;
    a += 1 << n;
    for (int i = 1; i < n / 2; i++) {
        a += 1 << i;
    }
    for (int i = n / 2; i < n; i++) {
        b += 1 << i;
    }
    cout << a - b << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

B - Phoenix and Beauty

题意

向一个长为 $n$ 的数组中插入一些数,使得每个长为 $k$ 的连续子数组的和为定值。

题解

将原数组中的每个数都用 $k$ 个数代替,为了保证 $k$ 个数能包含原数组中的数,记录原数组中不同值的个数,不足 $k$ 个补全至 $k$ 个即可。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, k; cin >> n >> k;
    set<int> st;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        st.insert(x);
    }
    if (st.size() > k) {
        cout << "-1" << "\n";
        return;
    }
    if (st.size() < k) {
        for (int i = 1; i <= n; i++) {
            st.insert(i);
            if (st.size() == k) break;
        }
    }
    cout << n * k << "\n";
    for (int i = 0; i < n; i++) {
        for (int j : st) cout << j <<  ;
    }
    cout << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

C - Phoenix and Distribution

题意

将字符串 $s$ 分为 $k$ 个非空串,找出使得 $k$ 个非空串中字典序最大的字符串字典序最小的方案。

题解

先给每个字符串分配一个字母保证非空,此时如果只剩下一种字母,给字典序最小的一些字符串循环分配即可。

如果剩下的字母多于一种,则全部分给一个字符串,因为这样分较大的字母最靠后,字典序最小。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, k; cin >> n >> k;
    string str; cin >> str;
    int cnt[26] = {};
    for (char c : str) cnt[c - a]++;
    string s[k];
    vector<char> init_s;
    int len = -1;
    for (int i = 0; i < 26; i++) {
        if (cnt[i] > 0) {
            if (len == -1) len = min(k, cnt[i]);
            int need = k - init_s.size();
            int mi = min(need, cnt[i]);
            for (int j = 0; j < mi; j++) {
                init_s.push_back(char(a + i));
            }
            cnt[i] -= mi;
        }
    }
    for (int i = 0; i < k; i++) {
        s[i] += init_s[i];
    }
    int type = 0;
    for (int i = 0; i < 26; i++) {
        type += cnt[i] > 0;
    }
    for (int i = 0; i < 26; i++) {
        if (cnt[i] > 0) {
            for (int j = 0; j < cnt[i]; j++) {
                if (type == 1) s[j % len] += char(a + i);
                else s[0] += char(a + i);
            }
        }
    }
    sort(s, s + k);
    cout << s[k - 1] << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

 

Codeforces Round #638 (Div. 2)

标签:return   str   题解   back   names   数列   进制   oid   set   

原文地址:https://www.cnblogs.com/Kanoon/p/12815637.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!