PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07
Tester: sushil2006
Editorialist: iceknight1093
DIFFICULTY:
Simple
PREREQUISITES:
None
PROBLEM:
You’re given two binary strings A and B, both of length N.
In one move, you can either flip all characters in a substring of A, or reverse a substring of A.
Find a sequence of no more than \left\lceil \frac{N}{2} \right\rceil operations that will result in both strings becoming equal.
EXPLANATION:
There are probably several different ways to achieve this, here’s one of them.
Call an index i bad if A_i \neq B_i. Our aim is to ensure that there are no bad indices in the end.
Note that performing a flip operation on a bad index will make it no longer bad, and vice versa.
We’re allowed to make at most \left\lceil \frac{N}{2} \right\rceil operations.
So, if there are \leq \left\lceil \frac{N}{2} \right\rceil bad indices initially, we can simply perform a single flip operation on each of them individually, and we’ll be done.
What if there are more than \left\lceil \frac{N}{2} \right\rceil bad indices initially?
In this case, first perform the flip operation on the entire string A. This will change all bad indices to not bad and vice versa; so after this operation the number of bad indices will be \lt N - \left\lceil \frac{N}{2} \right\rceil, which is \lt \left\lceil \frac{N}{2} \right\rceil.
We’ve used one operation, and now there are \lt \left\lceil \frac{N}{2} \right\rceil bad indices so we can just use one operation for each of them like the first case.
TIME COMPLEXITY:
\mathcal{O}(N) per testcase.
CODE:
Author's code (C++)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF (int)1e18
mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());
void Solve()
{
int n; cin >> n;
string a, b; cin >> a >> b;
int p = 0;
vector <array<int, 3>> ans;
while (p < n){
if (a[p] == b[p]){
p++;
continue;
}
if (p + 1 == n || a[p + 1] == b[p + 1]){
ans.push_back({1, p, p});
p++;
continue;
}
if (a[p] == a[p + 1]){
ans.push_back({1, p, p + 1});
p += 2;
} else {
ans.push_back({2, p, p + 1});
p += 2;
}
}
cout << ans.size() << "\n";
for (auto [type, l, r] : ans){
l++;
r++;
cout << type << " " << l << " " << r << "\n";
}
}
int32_t main()
{
auto begin = std::chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
cin >> t;
for(int i = 1; i <= t; i++)
{
//cout << "Case #" << i << ": ";
Solve();
}
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n";
return 0;
}
Editorialist's code (PyPy3)
for _ in range(int(input())):
n = int(input())
a = input()
b = input()
bad = 0
for i in range(n):
bad += a[i] != b[i]
ops = []
if bad > (n+1)//2: ops.append((1, 1, n))
for i in range(n):
if (a[i] != b[i]) ^ (bad > (n+1)//2): ops.append((1, i+1, i+1))
print(len(ops))
for op in ops: print(*op)