[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:
- They select a character $x$ from their own string.
- They replace one
?
in $f$ with $x$.- 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;
}