PROBLEM LINK:
Author: Praveen Dhinwa
Tester: Hasan Jaddouh
Editorialist: Sidhant Bansal
DIFFICULTY -
Easy - Medium
PROBLEM -
Given a grid of size 2 * n, where in some cells are marked SPECIAL. You have to put minimum line segments (walls) of any length you want such that each component made by the walls contains at most one cell which is marked SPECIAL.
EXPLANATION -
The solution is greedy and constructive in approach. There are 3 cases possible -
Case 1 - Both the rows has at least one snake.
Here we will firstly prove that putting an entire horizontal line segment is better than not putting one.
PROOF -
Use of NO horizontal line is only possible when there are no two snakes one below the other, so that means that each column has at most one snake, therefore the answer would be no. of snakes - 1 in case we do not use horizontal line. But, if we use the horizontal line we can see that the first snake in row 0 and the first snake in row 1 would be satisfied by only vertical line segment whereas earlier(with NO horizontal line segment) they required 2. This statement is false for the corner case when the row 0 has only 1 snake and also row 1 has only 1 snake. So this can be considered as a corner case, but apart from this in all the other cases, we can see that we have actually saved using one vertical line by introducing the horizontal line. Meaning that this horizontal line compensates for the vertical line that we saved. So the introduction of this horizontal line segment is equivalent to us for the first 2 snakes, but we can see that for the remaining snakes, we have a similar configuration to the previous case (when we did NOT use the horizontal line segment) BUT this time there is a horizontal line segment which is obviously more beneficial and ensures that the answer would either remain same or improve.
After the entire horizontal line segment between row 0 (0 - based indexing) and row 1 is made sound proof (add 1 to the answer for this line segment), a greedy solution is implemented. Notice here that because both the rows have snakes therefore there needs to be a horizontal segment and since we are free to make it of more length without increasing the cost, therefore the horizontal segment is made from one side of the grid to the opposite. Now we can greedily position the vertical segments, we will move from left to right and count the no. of snakes in the current compartment of row 0 and row 1, we will place the vertical line segment whenever we observe that the count of snakes in either row becomes greater than 1 and by placing the line segment, we now have opened a new compartment whose count of both the snakes would be 0 and updated accordingly.
Case 2 - Only a single row has all the snakes, then the no. of vertical line segments required is no. of snakes - 1.
Case 3 - No snake is there in the grid, then the answer is 0.
Below is the C++ implementation of the above mentioned logic -
#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
int cnt[2];
string s[2];
void solve(){
int n;
cin>>n;
cin>>s[0]>>s[1];
cnt[0] = cnt[1] = 0;
for(int i = 0; i < 2; i++){
for(int j = 0; j < n; j++){
if(s[i][j] == '*') cnt[i]++;
}
}
int ans = 0;
if(cnt[0] > 0 and cnt[1] > 0){ //Case 1
ans = 1;
cnt[0] = cnt[1] = 0;
for(int i = 0; i < n; i++){
if(s[0][i] == '*') cnt[0]++;
if(s[1][i] == '*') cnt[1]++;
if(cnt[0] > 1 or cnt[1] > 1){
ans++;
cnt[0] = cnt[1] = 0;
i--;
}
}
}
else if((cnt[0] == 0 and cnt[1] > 0) or (cnt[1] == 0 and cnt[0] > 0)){ //Case 2
ans = max(cnt[0], cnt[1]) - 1;
}
else{ //Case 3
ans = 0;
}
cout<<ans<<endl;
}
int main(){
int t;
cin>>t;
while(t--) solve();
}
Time Complexity - O(N)