Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
First ignore the distance- rule. For any one color used times, adjacency alone demands at least other colors between its copies. What does that say about the most frequent color?
Let and . No answer can use more than of that dominant color, so the target length is forced to be Now the real job is construction, not optimization.
Both forbidden distances, and , are odd. So every forbidden pair connects an odd position to an even position. Filling odd and even slots intentionally makes the scary rule much less scary.
After possibly cutting the largest count down to , every target count is at most . If some color has exactly copies, put it on every odd position and put the other two colors on even positions. Done.
Dead giveaway: otherwise sort target counts as with colors . Let , . Fill odd slots with , even slots with , then interleave. The only split color is , and its two groups are far enough apart because whenever the even group exists.
Let be the largest of , and let be the sum of the other two counts.
Even if the distance- rule did not exist, adjacency already says that copies of one color need at least non-that-color separators. So the most frequent color can contribute at most copies. Therefore every answer has length at most
This bound is tight. We keep all non-dominant colors, and if the dominant color has more than copies, we simply use only of it. Call the resulting target counts , and let
By construction,
So the whole problem becomes: construct a valid string for any three target counts whose maximum is at most . This is where the distance- rule stops looking like black magic.
Both forbidden distances are odd:
So every forbidden pair connects an odd position to an even position. There are no constraints between two odd positions, and no constraints between two even positions. Nice. The beast has a zipper.
Let
Think of building two arrays: one for odd slots and one for even slots, then interleaving them.
If some color has exactly copies, put that color in all odd slots. Put the other two colors, in any order, into the even slots.
Every forbidden pair is odd-even, and the odd color never appears on even positions, so no equal forbidden pair can happen. That is embarrassingly effective, which is the best kind of effective.
Otherwise, no color has copies. Sort the target counts:
and call their colors , , and , respectively. So is the largest color, is the middle color, and is the smallest color.
Fill the slots like this:
Then interleave odd slot , even slot , odd slot , even slot , and so on.
The counts are exactly right:
and
Now check validity. Color appears only on even slots, and color appears only on odd slots, so they cannot conflict with themselves because all forbidden edges are odd-even.
Only appears on both parities. Its odd occurrences are a prefix ending at odd-slot index . Its even occurrences are a suffix starting at even-slot index .
If there is no even suffix, there is nothing to prove. Otherwise . Suppose . Then
but also , contradiction. Hence
So the first even is at least two slot-indices after the last odd :
An odd slot is real position , and an even slot is real position . If , their real distance is
So equal copies are never adjacent and never distance apart. Valid.
The construction writes the answer once, so each test case costs
time and memory. Over the whole input this is
which is easily fine because the total available ghostfires are bounded by .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
array<char, 3> color = {'R', 'G', 'B'};
while (T--) {
vector<int> cnt(3);
cin >> cnt[0] >> cnt[1] >> cnt[2];
int big = max_element(cnt.begin(), cnt.end()) - cnt.begin();
int sum = cnt[0] + cnt[1] + cnt[2];
int others = sum - cnt[big];
if (cnt[big] > others + 1) cnt[big] = others + 1;
int n = cnt[0] + cnt[1] + cnt[2];
int oddSlots = (n + 1) / 2;
int evenSlots = n / 2;
string odd, even;
odd.reserve(oddSlots);
even.reserve(evenSlots);
int fullOdd = -1;
for (int i = 0; i < 3; ++i) {
if (cnt[i] == oddSlots) {
fullOdd = i;
break;
}
}
if (fullOdd != -1) {
odd.append(oddSlots, color[fullOdd]);
for (int i = 0; i < 3; ++i) {
if (i != fullOdd) even.append(cnt[i], color[i]);
}
} else {
vector<int> id = {0, 1, 2};
sort(id.begin(), id.end(), [&](int a, int b) {
return cnt[a] < cnt[b];
});
int z = id[0]; // smallest: odd suffix
int x = id[1]; // middle: split color
int y = id[2]; // largest: even prefix
odd.append(oddSlots - cnt[z], color[x]);
odd.append(cnt[z], color[z]);
even.append(cnt[y], color[y]);
even.append(evenSlots - cnt[y], color[x]);
}
string ans;
ans.reserve(n);
for (int i = 0; i < oddSlots; ++i) {
ans.push_back(odd[i]);
if (i < evenSlots) ans.push_back(even[i]);
}
cout << ans << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
array<char, 3> color = {'R', 'G', 'B'};
while (T--) {
vector<int> cnt(3);
cin >> cnt[0] >> cnt[1] >> cnt[2];
int big = max_element(cnt.begin(), cnt.end()) - cnt.begin();
int sum = cnt[0] + cnt[1] + cnt[2];
int others = sum - cnt[big];
if (cnt[big] > others + 1) cnt[big] = others + 1;
int n = cnt[0] + cnt[1] + cnt[2];
int oddSlots = (n + 1) / 2;
int evenSlots = n / 2;
string odd, even;
odd.reserve(oddSlots);
even.reserve(evenSlots);
int fullOdd = -1;
for (int i = 0; i < 3; ++i) {
if (cnt[i] == oddSlots) {
fullOdd = i;
break;
}
}
if (fullOdd != -1) {
odd.append(oddSlots, color[fullOdd]);
for (int i = 0; i < 3; ++i) {
if (i != fullOdd) even.append(cnt[i], color[i]);
}
} else {
vector<int> id = {0, 1, 2};
sort(id.begin(), id.end(), [&](int a, int b) {
return cnt[a] < cnt[b];
});
int z = id[0]; // smallest: odd suffix
int x = id[1]; // middle: split color
int y = id[2]; // largest: even prefix
odd.append(oddSlots - cnt[z], color[x]);
odd.append(cnt[z], color[z]);
even.append(cnt[y], color[y]);
even.append(evenSlots - cnt[y], color[x]);
}
string ans;
ans.reserve(n);
for (int i = 0; i < oddSlots; ++i) {
ans.push_back(odd[i]);
if (i < evenSlots) ans.push_back(even[i]);
}
cout << ans << '\n';
}
}