PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07
Tester: archit
Editorialist: raysh07
DIFFICULTY:
Simple
PREREQUISITES:
None
PROBLEM:
You are given a binary string S, convert it to T using at most 3 \cdot N operations. In one operation, you can choose i (1 \le i < N) such that S_{i} = 1 and flip S_{i + 1}. Find the operation sequence if possible.
EXPLANATION:
Let us first observe when it is possible to convert S to T.
Suppose S_i = 1. Then, we can make S_{i + 1} = 1 as well (if it is 0, just do one operation at i). Proceeding similarly, we can actually make all S_j = 1 for all j > i to get S_1 S_2 ... S_{i - 1}1 1 .. 1
How is this useful? Well, we can then iterate from j = N to i + 1, and if S_j \ne T_j, we can simply do one operation on the index j - 1. This will flip S_j, and it is guaranteed S_{j - 1} = 1 because we iterated in reverse.
Thus, we can make the entire suffix S[i + 1, N] match T[i + 1, N] just because S_i = 1.
But notice, the above only works for the suffix of characters after the first 1 position in S. That is, let p denote the first 1 position in S; then we can arbitrarily change the characters S_{p + 1}, S_{p + 2}, ..., S_N but not S_1 S_2 .... S_{p}, hence S_i = T_i should be satisfied for all 1 \le i \le p without doing any operations.
We can check the condition with simple loop, and then convert S_{p + 1} ... S_N all to 1, and then loop in reverse equating it to T. Check the solution for more details. The solution uses at most 2 \cdot N operations.
TIME COMPLEXITY:
\mathcal{O}(N) per testcase.
CODE:
Editorialist's Code (C++)
#include <bits/stdc++.h>
using namespace std;
int main(){
int t; cin >> t;
while (t--){
int n; cin >> n;
string s, t; cin >> s >> t;
int p = n;
for (int i = 0; i < n; i++){
if (s[i] == '1'){
p = i;
break;
}
}
bool good = true;
for (int i = 0; i <= p; i++){
if (s[i] != t[i]){
cout << -1 << "\n";
good = false;
break;
}
}
if (!good) continue;
vector <int> ans;
for (int i = p + 1; i < n; i++){
if (s[i] == '0'){
ans.push_back(i);
s[i] = '1';
}
}
for (int i = n - 1; i > p; i--){
if (s[i] != t[i]){
ans.push_back(i);
}
}
cout << ans.size() << "\n";
for (auto x : ans){
cout << x << " ";
}
cout << "\n";
}
return 0;
}