
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;
}
                

















