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.
You only need one letter type to become one contiguous block. So compute the minimum cost to group all as, compute the same for all bs, and take the smaller answer.
If you decide to group one fixed character, the relative order of those characters never needs to change. Adjacent-swapping two equal letters is pointless, and swapping two chosen letters past each other changes nothing useful.
Let the chosen character appear at positions in 0-indexing. If their final block starts at position , then they should end at .
The cost for a chosen start is Rewrite it as Now it is just “pick one number minimizing sum of absolute distances.”
The best is the median of the values . So for each letter, build that adjusted position array, take its median, sum distances to it, then answer with the smaller of the two costs.
We need the minimum adjacent swaps so that all copies of either a or b form one continuous block.
The trap here is thinking we need to decide the whole final string. We don't. If we choose to group all as, then the bs are just filler around that block. Same for grouping all bs. So solve this smaller problem:
Given the positions of one character, what is the minimum adjacent swaps needed to move all of them into consecutive positions?
Then do it for a, do it for b, and take the minimum.
Grouping One Character
Suppose we are grouping some character c, and it appears times at 0-indexed positions:
In the final string, these characters must occupy some consecutive block:
The first occurrence goes to , the second to , and so on.
Why can we assume that order? Because equal characters do not need to cross each other. If two as swap places, the string doesn't become more useful; it is just wasting swaps. So the optimal matching preserves order.
For a fixed block start , the number of adjacent swaps needed is:
Each chosen character must move that many positions, and adjacent swaps exactly measure total movement across other characters.
Now simplify the expression:
So the cost becomes:
Let:
Now the problem is:
Pick an integer minimizing .
Classic median moment. The value minimizing sum of absolute distances is any median of the array.
So the optimal cost for this character is:
That is the whole problem. No DP, no graph nonsense, no cursed string simulation.
Why This Works
Adjacent swaps can be viewed as moving selected characters left or right through the other character. If an occurrence moves from position to target position , it contributes swaps.
Since the selected characters are identical, preserving their order is always optimal. Therefore, choosing a final consecutive block completely determines the target position of each occurrence.
The only remaining freedom is the block start . After subtracting from each original position, the targets all collapse to the same unknown , and minimizing absolute deviations gives the median.
Algorithm
For each test case:
a.b.For a position list pos:
The adjusted array is already nondecreasing because positions strictly increase, so no sorting is needed.
Complexity
Each test case is processed in time.
Across all tests, the total complexity is:
Memory usage is for the stored positions. Costs can be up to about , so use long long.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll costToGroup(const vector<int>& pos) {
int k = (int)pos.size();
if (k <= 1) return 0;
vector<ll> q(k);
for (int i = 0; i < k; i++) {
q[i] = (ll)pos[i] - i;
}
ll med = q[k / 2];
ll cost = 0;
for (ll x : q) cost += llabs(x - med);
return cost;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
vector<int> a, b;
for (int i = 0; i < n; i++) {
if (s[i] == 'a') a.push_back(i);
else b.push_back(i);
}
cout << min(costToGroup(a), costToGroup(b)) << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll costToGroup(const vector<int>& pos) {
int k = (int)pos.size();
if (k <= 1) return 0;
vector<ll> q(k);
for (int i = 0; i < k; i++) {
q[i] = (ll)pos[i] - i;
}
ll med = q[k / 2];
ll cost = 0;
for (ll x : q) cost += llabs(x - med);
return cost;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
vector<int> a, b;
for (int i = 0; i < n; i++) {
if (s[i] == 'a') a.push_back(i);
else b.push_back(i);
}
cout << min(costToGroup(a), costToGroup(b)) << '\n';
}
}