Codeforces Round 921 (Div. 2)

本文详细解读了CodeforcesRound921中的三个题目,涉及字符串构造、最大公因数优化和字符串子序列验证,提供了关键代码片段。
摘要由CSDN通过智能技术生成

在这里插入图片描述

Codeforces Round 921 (Div. 2)

Codeforces Round 921 (Div. 2)

A. We Got Everything Covered!

题意:找到一个字符串s,使得所有可能长度为n的字符串都可以用前k个小写字母组成,并为s的子序列。
思路:A的题意理解对C很有用

  • 首先是长度为n的字符串,该字符串由前k个小写字母组成;
  • 任意的字符串n,都可以在字符串s中找到子序列n(可不相邻,只要顺序一致),即所有长度为n的前k个字符的排列组合;
  • 符合条件的字符串s长度最短为k*n,那么我们只需要输出n组前k个字符组成字符串s。

AC code:

void solve() {
    cin >> n >> k;
    while (n --) {
        for (int i = 0; i < k; i ++)
            cout << (char)('a' + i);
    } cout << endl;
}

B. A Balanced Problemset?

题意:将正整数x分成n份,最大化这n份的最大公因数GCD。

思路:

  • 首先肯定是尽可能的平分x,最大的可能就是x正好可以被n整除,GCD最大为n/x;
  • 由此可以确定,存在的最大GCD一定被x整除,且最大的可能就是n/x;
  • 这里可以去枚举x的所有因子,用质数筛的方式即可;

AC code:

void solve() {
    cin >> x >> n;
    int mx = 0;
    for (int i = 1; i <= x / i; i ++) {
        if (x % i == 0) {
            if (x / i * n <= x) {
                mx = max(mx, x / i);
            }
            if (i * n <= x) {
                mx = max(mx, i);
            } else {
                cout << mx << endl;
                return;
            }
        }
    } cout << mx << endl;
}

C. Did We Get Everything Covered?

题意:现在给出一个字符串,判断是不是符合A中条件的字符串,若不是,则需找到一个不属于该字符串子序列的长度为n的字符串。

思路:

  • 首先,判断字符串是否符合条件,即字符串s是否存在所有可能的长度为n的字符串的子序列,且由前k个字母组成:
    • A中我们创造这样的字符是找n组包含k个字符组成的字符串s,现在反过来,寻找是否存在n组k个字母的排列;
    • 这里可以用map从前往后遍历,每存在k个不同字符为一组,当出现>=n组的情况则s符合条件;
  • 当字符串s不符合条件的时候,我们需要找到一个长度为n且非s的子序列的一个字符串:
    • 在用map记录组数的时,我们记录每组最后的一个字符到一个新的字符串now中,因为组数是小于n的,所以该字符串now一定小于n;
    • 现在字符串now一定是不属于字符串s的字符串的一个连续子串:
      • 第一种情况该连续子串中缺少前k个字母中的一个,遍历子串,找到该字符并添加到now的末尾, 不足长度n后缀补字符’a’;
      • 第二种情况就是我们记录的最后一组字符存在前k个字符,直接后缀补字符’a’即可。
  • 详见代码

AC code:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define db double
#define pb push_back
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
 
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 2e5+10, M = 2001;
const int INF = 0x3f3f3f3f3f, mod = 998244353;
int T, n, m, k;
 
void solve() {
    cin >> n >> k >> m;
    string s; cin >> s;
 
    int flag = 0;
    string now = "";
    map<char, int> mp;
    for (char c : s) {
        mp[c] ++;
        if (mp.size() == k) {
            now.pb(c);
            flag ++;
            mp.clear();
        }
        if (flag == n) {
            cout << "YES" << endl;
            return;
        }
    }
    cout << "NO" << endl;
    char pp;
    for (int i = 0; i < k; i ++) {
        char c = 'a' + i;
        if (!mp[c]) {
            pp = c;
            break;
        }
    }
    now += pp;
    n -= now.size();
    cout << now;
    while (n --) cout << 'a';
    cout << endl;
}
 
signed main() {
    fast();
    
    T = 1;
    cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值