CF794C Naming Company Solution


[CF794C Naming Company] Solution

Problem link: CF794C Naming Company

Problem Statement:

Here is the modified text, formatted in Markdown with inline formulas:

A and B each have a string of length $n$, consisting of lowercase letters, denoted by $s$ and $t$ respectively. There is also a target string $f$ of length $n$, initially composed of ? symbols.

Now, A and B take turns performing the following operation:

  1. They select a character $x$ from their own string.
  2. They replace one ? in $f$ with $x$.
  3. They remove $x$ from their own string.

The game ends when there are no more ? symbols in $f$.

A’s goal is to make the lexicographical order of $f$ as small as possible, while B’s goal is to make it as large as possible.

A is the first player. Your task is to determine the final string $f$ after the game ends.

Note: The strings $s$ and $t$ may contain multiple duplicate characters, and only one character can be removed at a time.

Data range:

$1 \le n \le 3\times 10^5$

One obvious greedy algorithm is for both players to fill the beginning of $f$ with characters that benefit them the most.

However, this greedy strategy is incorrect because it results in a larger answer when the smallest character chosen by A is greater than the largest character chosen by B.

So, what can we do instead? We can use a “reverse greedy strategy” in such cases, which ensures that the problematic position in $f$ is filled with a character that is not greater than the largest character chosen by B.

Time complexity: $\mathcal{O}(n)$

Code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(3e5 + 15))

char s[N];
int n,a[N],b[N],f[N];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> (s + 1); n = strlen(s + 1);
    for(int i = 1; i <= n; i++) a[i] = s[i] - 'a';
    cin >> (s + 1); n = strlen(s + 1);
    for(int i = 1; i <= n; i++) b[i] = s[i] - 'a';
    sort(a + 1, a + 1 + n, less<int>());
    sort(b + 1, b + 1 + n, greater<int>());
    int x = 0, y = 0, pos = n;
    for(int i = 1; i <= n; i++)
    {
        if(a[x + 1] >= b[y + 1]) { pos = i - 1; break; }
        (i & 1) ? (f[i] = a[++x]) : (f[i] = b[++y]);
    }
    x = y = (n >> 1) + 1; if(n & 1) ++x;
    for(int i = n; i > pos; i--) {
        ((pos + n - i + 1) & 1) ? (f[i] = a[--x]) : (f[i] = b[--y]);
    }
    for(int i = 1; i <= n; i++) { cout << char(f[i] + 'a'); } cout << '\n';
    return 0;
}

Author: q779
Reprint policy: All articles in this blog are used except for special statements CC BY-NC-ND 4.0 reprint polocy. If reproduced, please indicate source q779 !
评论
  TOC