Codeforces Round #739 (Div. 3)(补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #739 (Div. 3)(补题)相关的知识,希望对你有一定的参考价值。

D. Make a Power of Two



题意: 对于给定的一个数,有两种操作,可以选择任意位置删除这个数,也可以在数的右边加一个数,问操作至少几次,可以使这个数变成2的证次幂
思路: 直接提前预处理出来所有的2的整次幂的数,然后用当前数与所有2的证次幂的所有数进行比较,判断操作次数,最后取最小值。
当前数与2的整次幂的数的比较,就利用双指针就可以判断,拿着输入的 s s s串,与模式串进行匹配,因为s串是通过删除,右边添加的操作,可以直接利用双指针看有几对一样的,剩下都不是一样的

#include <bits/stdc++.h>
using namespace std;
#define ll long long
string s;
string str[100];
int solve(string b, string a) {
    int j = 0;
    int lena = a.size(), lenb = b.size();
    for (int i = 0; i < lena; i++) {
        if (j == lenb) {
            break;
        }
        if (a[i] == b[j]) {
            j++;
        }
    }
    return lena + lenb - 2 * j;
}
int main() {
    ll now = 1;
    for (int i = 0; i <= 60; i++) {
        str[i] = to_string(now << i);
    }
    int t;
    cin >> t;
    while (t--) {
        cin >> s;
        int res = 100;
        for (int i = 0; i <= 60; i++) {
            res = min(res, solve(str[i], s));
        }
        cout << res << endl;
    }
}

E. Polycarp and String Transformation



题意: 给定一个字符串 s s s,和一个空串 t t t, t = t + s t=t+s t=t+s,然后再选定 s s s串中的一个字母,使得 s s s串中所有的这个字母都删去,在 t = t + s t=t+s t=t+s,反复上述操作,知道 s s s串为空,现在给你 t t t串,让你输出 s s s串和删除字母的顺序
思路: 先根据 s s s字符串里的每个字母最后出现的位置,判断删除字母的顺序。再存每个字母在几个阶段出现。然后在每次读入字符是,也要读入它们的阶段数,即阶段数乘上这个字母的数量,现在长度和 s s s串是否相同,不相同就-1,相同再模拟一遍题目的要求,我们根据之前记录的字母删除顺序,构造出一个字符串,看最后构造出来的是否与 s s s串相同。

#include <bits/stdc++.h>
using namespace std;
string s;
vector<int> a;
bool b[30];
int pos[30];
int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        a.clear();
        memset(b, 0, sizeof(b));
        memset(pos, 0, sizeof(pos));
        cin >> s;
        for (int i = s.size() - 1; i >= 0; i--) {
            if (!b[s[i] - 'a']) {
                b[s[i] - 'a'] = 1;
                a.push_back(s[i]);
            }
        }
        for (int i = 0; i < a.size(); i++) {
            pos[a[i] - 'a'] = a.size() - i;
        }
        int now = 0;
        string res;
        bool flag = 0;
        for (int i = 0; i < s.size(); i++) {
            res += s[i];
            now += pos[s[i] - 'a'];
            if (now > s.size()) break;
            if (now == s.size()) {
                string q, dex = res;
                for (int i = a.size() - 1; i >= 0; i--) {
                    q += dex;
                    string dey;
                    for (int k = 0; k < dex.size(); k++) {
                        if (dex[k] != a[i]) {
                            dey += dex[k];
                        }
                    }
                    dex = dey;
                }
                if (q == s) {
                    flag = 1;
                    break;
                }
            }
        }
        if (!flag)
            puts("-1");
        else {
            cout << res << " ";
            for (int i = a.size() - 1; i >= 0; i--) {
                printf("%c", a[i]);
            }
            cout << '\\n';
        }
    }
    return 0;
}

F2. Nearest Beautiful Number (hard version)(和F1一样的)


题意: 一个数中,有至多 k k k个数字不同,这个数字就是 k k k美丽数字,现在让你给你一个数 n n n,让你输出 x x x ( x > = n ) (x>=n) (x>=n), x x x是符合题意的最小的 k k k美丽数
思路: 从后往前枚举每个数,因为从后往前,每个数对这个数本身的权重是越来越大的,然后改当前这个枚举这位的数字,枚举肯定要枚举比它大的,例如 123 123 123,枚举第三位的时候,要从4到9枚举,因为 x > = n x>=n x>=n,枚举第二位的时候,要从 3 3 3到9,如果枚举到当前位置的时候,不同数字的个数大于要求 K K K,那就再枚举别的数。如果符合题意,那就输出答案,输出的时候,如果不同的数字个数小于K,那就在后面一直加0即可,加到长度恰好为止,如果不同数字个数等于K,那就再在后面一直加出现数字最小的那个就行,不可能大于,大于就不输出了。

#include <bits/stdc++.h>
using namespace std;
int t, n, k;
bool check(int x, int c) {
    vector<int> A(10);
    while (x) {
        A[x % 10] = 1;
        x /= 10;
    }
    int cnt = 0;
    for (auto x : A) {
        cnt += x;
    }
    return cnt <= k;
}

int get(int x, int c) {
    int u = x;
    vector<bool> A(10);
    while (x) {
        A[x % 10] = 1;
        x /= 10;
    }
    int cnt = 0;
    for (auto x : A) {
        cnt += x;
    }
    if (cnt == k) {
        int y = 0;
        for (int i = 9; i >= 0; i--) {
            if (A[i]) {
                y = i;
            }
        }
        while (c--) u = u * 10 + y;
        return u;
    }
    while (c--) u = u * 10;
    return u;
}
int main() {
    cin >> t;
    while (t--) {
        scanf("%d%d", &n, &k);
        int N = n;
        bool flag = 0;
        for (int i = 0; i < 10 && !flag; i++, n /= 10) {
            int g = n % 10;
            if (i != 0) ++g;
            for (int j = g; j < 10 && !flag; j++) {
                if (check(n / 10 * 10 + j, i)) {
                    flag = 1;
                    printf("%d\\n", get(n / 10 * 10 + j, i));
                }
            }
        }
    }
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于Codeforces Round #739 (Div. 3)(补题)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #739 (Div. 3) 题解

Codeforces Round #739 (Div. 3)A-F2

Codeforces Round #739 (Div. 3) ABCDEF1F2题解

Codeforces Round #739 (Div. 3) ABCDEF1F2题解

Codeforces Round #739 (Div. 3)(补题)

Codeforces Round #739 (Div. 3) F1. Nearest Beautiful Number (easy version)