Minimizing Binary statements: Transforming a Binary String to all Zeroes
Last Updated :
07 Nov, 2023
Given a set of N binary statements represented by a string S, where '1' represents a true statement and '0' represents a false one. You can perform the following operation multiple times: choose two indices i and j (1 ≤ i < j ≤ N) such that j - i ≥ 2 and toggle the states of statements i and j, the task is to determine whether it is possible to make all N statements false using these operations. If possible, calculate the minimum number of operations needed to achieve this. If it's not possible to make all statements false, return -1.
Examples:
Input: N = 6, S = 101101
Output: 2
Explanation: Here, we can perform the operation with ((i, j) = (1, 3) and then with (i, j) = (4, 6) to make all the statements false.
Input: N = 4, S = 1111
Output: -1
Explanation: Here, we can't make all statements false with any operation.
Approach: To solve the problem follow the below observations:
- Case I: In each operation, the count of 1 increases by 0, +2, or -2, so the objective is unachievable if the count of 1 is odd. In all the below cases we consider the count of 1 is even.
- Case II: If there is no 1, then nothing to do.
- Case III: If a count of 1 is greater than or equal to 4, then Let x1, x2,…,xk(k is the count of 1) be the true statements from left to right. Then, one can achieve the objective in k/2 operations by changing the states of statements 1 and xk/2+1, statements 2 and xk/2+2, and so on.
- Case IV: The count of 1 is 2, If the true statements are not adjacent, the answer is 1. Below, assume that they are adjacent, and let X be the statement to the left and Y be the statement to the right.
- If X >=3 , one can achieve the objective in two operations by changing the states of staements 1 and X and then by changing the states of staements 1 and Y.
- If X+1 ≤ N-2, one can again achieve the objective in two operations by changing the states of staements 1 and N and then by changing the states of staements X and Y.
- Case V: Neither of the above is satisfied if X < 3 and X+1>N-2, which happens only if N=3 or 4.
- If N=3, then S is 011 or 110, in which case one can only flip coins 1 and 3, so the objective is unachievable.
- If N=4, X<3, and X+1>N-2, then S is 0110, in which case the objective is achievable in three operations (0110→1111→0101→0000).
Steps to implement the above approach:
- Read the integer 'n', the number of statements, and the string 's', representing the current state of the statements.
- Count the number of '1's in the string 's' using the count() function. Let's call this count 'one'.
- Check if the count 'one' is odd:
- If odd, return -1, indicating that it's not possible to make all statements false.
- Initialize a boolean variable 'adj' as false. This will be used to check if adjacent pairs of '1's exist.
- Iterate through the characters of the string 's' from index 0 to 'n-2':
- If the current character and the next character are both '1's, set 'adj' to true.
- If 'one' is not equal to 2 or 'adj' is false, calculate the minimum number of operations needed:
- If 'one' is greater than or equal to 4, or 'one' is 0, or 'adj' is false, return 'one / 2' as the minimum number of operations.
- If 'one' is equal to 2 and 'adj' is true, find the position of the leftmost '1' in the string 's'. Let's call this position 'x'.
- Check for special cases:
- If 'n' is 3, return -1 as it's not possible to achieve the objective.
- If 'n' is 4 and 's' is "0110", return 3 as it can be achieved in 3 operations.
- If none of the special cases apply, check if the position 'x' is greater than or equal to 3:
- If yes, return 2 as the objective can be achieved by flipping statements 1 and 'x', then statements 1 and the position of the second '1'.
- If 'x+1' is less than or equal to 'n-2':
- If yes, return 2 as the objective can be achieved by flipping statements 1 and 'n', then statements 'x' and the position of the second '1'.
- If none of the above conditions are satisfied, return -1 as the objective cannot be achieved.
Below is the implementation of the above approach:
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Function to solve the
// problem for a single test case
int IsPossibleToMakeAllFalse(string s, int n)
{
// Count the number of
//'1's in the string S
int one = count(s.begin(), s.end(), '1');
// If the count 'one' is odd,
// it is not possible to make
// all statements are false
if (one & 1)
return -1;
// Check if the '1's in the
// string S are adjacent or not
bool adj = 0;
for (int i = 0; i < n - 1; i++)
if (s[i] == '1' and s[i] == s[i + 1])
adj = 1;
// If the count 'one' is not 2
// or the '1's are not
// adjacent, the objective is
// achievable in 'one/2'
// operations
if (one != 2 or !adj)
return one / 2;
// If the '1's are adjacent,
// find the position of the
// leftmost '1'
int x = 0;
while (s[x] != '1')
x++;
// Check for special cases
if (n == 3)
return -1;
if (n == 4 and s == "0110")
return 3;
// If 'x' is greater than or
// equal to 3, perform two operations:
// 1. Flip statements 1 and 'x'
// 2. Flip statements 1 and 'y', where
// 'y' is the position of the second '1'
if (x >= 3)
return 2;
// If 'x+1' is less than or equal
// to 'N-2', perform two operations:
// 1. Flip statements 1 and 'N'
// 2. Flip statements 'x' and 'y',
// where 'y' is the
// position of the second '1'
if (x + 1 <= n - 2)
return 2;
// If neither of the above
// conditions is satisfied,
// return -1 (unachievable)
return -1;
}
// Driver Code
int main()
{
int n = 6;
string s = "101101";
// Function Call
cout << IsPossibleToMakeAllFalse(s, n) << endl;
return 0;
}
Java
import java.util.Scanner;
public class Main {
// Function to solve the problem for a single test case
public static int isPossibleToMakeAllFalse(String s, int n) {
// Count the number of '1's in the string s
int one = 0;
for (char c : s.toCharArray()) {
if (c == '1') {
one++;
}
}
// If the count 'one' is odd, it is not possible to make all statements false
if (one % 2 != 0) {
return -1;
}
// Check if the '1's in the string s are adjacent or not
boolean adj = false;
for (int i = 0; i < n - 1; i++) {
if (s.charAt(i) == '1' && s.charAt(i) == s.charAt(i + 1)) {
adj = true;
break;
}
}
// If the count 'one' is not 2 or the '1's are not adjacent,
// the objective is achievable in 'one/2' operations
if (one != 2 || !adj) {
return one / 2;
}
// If the '1's are adjacent, find the position of the leftmost '1'
int x = 0;
while (s.charAt(x) != '1') {
x++;
}
// Check for special cases
if (n == 3) {
return -1;
}
if (n == 4 && s.equals("0110")) {
return 3;
}
// If 'x' is greater than or equal to 3, perform two operations:
// 1. Flip statements 1 and 'x'
// 2. Flip statements 1 and 'y', where 'y' is the position of the second '1'
if (x >= 3) {
return 2;
}
// If 'x+1' is less than or equal to 'N-2', perform two operations:
// 1. Flip statements 1 and 'N'
// 2. Flip statements 'x' and 'y', where 'y' is the position of the second '1'
if (x + 1 <= n - 2) {
return 2;
}
// If neither of the above conditions is satisfied, return -1 (unachievable)
return -1;
}
public static void main(String[] args) {
int n = 6;
String s = "101101";
// Function Call
System.out.println(isPossibleToMakeAllFalse(s, n));
}
}
Python3
# Function to solve the
# problem for a single test case
def IsPossibleToMakeAllFalse(s, n):
# Count the number of
#'1's in the string S
one = s.count('1')
# If the count 'one' is odd,
# it is not possible to make
# all statements are false
if one & 1:
return -1
# Check if the '1's in the
# string S are adjacent or not
adj = False
for i in range(n - 1):
if s[i] == '1' and s[i] == s[i + 1]:
adj = True
# If the count 'one' is not 2
# or the '1's are not
# adjacent, the objective is
# achievable in 'one/2'
# operations
if one != 2 or not adj:
return one // 2
# If the '1's are adjacent,
# find the position of the
# leftmost '1'
x = 0
while s[x] != '1':
x += 1
# Check for special cases
if n == 3:
return -1
if n == 4 and s == "0110":
return 3
# If 'x' is greater than or
# equal to 3, perform two operations:
# 1. Flip statements 1 and 'x'
# 2. Flip statements 1 and 'y', where
# 'y' is the position of the second '1'
if x >= 3:
return 2
# If 'x+1' is less than or equal
# to 'N-2', perform two operations:
# 1. Flip statements 1 and 'N'
# 2. Flip statements 'x' and 'y',
# where 'y' is the
# position of the second '1'
if x + 1 <= n - 2:
return 2
# If neither of the above
# conditions is satisfied,
# return -1 (unachievable)
return -1
# Driver Code
n = 6
s = "101101"
# Function Call
print(IsPossibleToMakeAllFalse(s, n))
C#
using System;
class Program
{
// Function to solve the problem for a vsingle test case
static int IsPossibleToMakeAllFalse(string s, int n)
{
// Count the number of '1's in the string s
int one = s.Split('1').Length - 1;
// If the count 'one' is odd, it is not possible to make all statements false
if (one % 2 != 0)
return -1;
// Check if the '1's in the string s are adjacent or not
bool adj = false;
for (int i = 0; i < n - 1; i++)
{
if (s[i] == '1' && s[i] == s[i + 1])
{
adj = true;
break;
}
}
// If the count 'one' is not 2 or the '1's are not adjacent, the objective is achievable in 'one/2' operations
if (one != 2 || !adj)
return one / 2;
// If the '1's are adjacent, find the position of the leftmost '1'
int x = 0;
while (s[x] != '1')
{
x++;
}
// Check for special cases
if (n == 3)
return -1;
if (n == 4 && s == "0110")
return 3;
// If 'x' is greater than or equal to 3, perform two operations:
// 1. Flip statements 1 and 'x'
// 2. Flip statements 1 and 'y', where 'y' is the position of the second '1'
if (x >= 3)
return 2;
// If 'x+1' is less than or equal to 'n-2', perform two operations:
// 1. Flip statements 1 and 'n'
// 2. Flip statements 'x' and 'y', where 'y' is the position of the second '1'
if (x + 1 <= n - 2)
return 2;
// If neither of the above conditions is satisfied, return -1 (unachievable)
return -1;
}
// Driver Code
static void Main()
{
int n = 6;
string s = "101101";
// Function Call
Console.WriteLine(IsPossibleToMakeAllFalse(s, n));
}
}
//This code is Contributed by chinmaya121221
JavaScript
function isPossibleToMakeAllFalse(s, n) {
// Count the number of '1's in the string s
const one = s.split('1').length - 1;
// If the count 'one' is odd, it is not possible to make all statements false
if (one % 2 !== 0)
return -1;
// Check if the '1's in the string s are adjacent or not
let adj = false;
for (let i = 0; i < n - 1; i++) {
if (s[i] === '1' && s[i] === s[i + 1]) {
adj = true;
break;
}
}
// If the count 'one' is not 2 or the '1's are not adjacent, the objective is achievable in 'one/2' operations
if (one !== 2 || !adj)
return Math.floor(one / 2);
// If the '1's are adjacent, find the position of the leftmost '1'
let x = 0;
while (s[x] !== '1') {
x++;
}
// Check for special cases
if (n === 3)
return -1;
if (n === 4 && s === "0110")
return 3;
// If 'x' is greater than or equal to 3, perform two operations:
// 1. Flip statements 1 and 'x'
// 2. Flip statements 1 and 'y', where 'y' is the position of the second '1'
if (x >= 3)
return 2;
// If 'x+1' is less than or equal to 'n-2', perform two operations:
// 1. Flip statements 1 and 'n'
// 2. Flip statements 'x' and 'y', where 'y' is the position of the second '1'
if (x + 1 <= n - 2)
return 2;
// If neither of the above conditions is satisfied, return -1 (unachievable)
return -1;
}
// Test case
const n = 6;
const s = "101101";
// Function call
console.log(isPossibleToMakeAllFalse(s, n));
Time Complexity: O(N)
Auxiliary Space: O(1)
Similar Reads
Minimizing Cost to Convert Binary String to Fair String Given a binary string S of size N. You had been given the task of converting the given string into a Fair string. You can do the following operation any number of times : If the ith character in S is 0, replace it with 1 using cost C[i].If the ith character in S is 1, replace it with 0 using cost C[
7 min read
Minimum steps to remove substring 010 from a binary string Given a binary string, the task is to count the minimum steps to remove substring "010" from this binary string. Examples: Input: binary_string = "0101010" Output: 2 Switching 0 to 1 at index 2 and index 4 will remove the substring 010. Hence the number of steps needed is 2. Input: binary_string = "
4 min read
Check if binary representations of 0 to N are present as substrings in given binary string Give binary string str and an integer N, the task is to check if the substrings of the string contain all binary representations of non-negative integers less than or equal to the given integer N. Examples: Input: str = â0110", N = 3 Output: True Explanation: Since substrings â0", â1", â10", and â11
9 min read
Minimize cost to convert all characters of a binary string to 0s Given a binary string, str, two integer arrays R[], and C[] of size N. Flipping all the characters from index i to R[i] requires C[i] cost. The task is to minimize the cost required to convert the given binary string to only 0s. Examples: Input: str = â1010â, R[] = {1, 2, 2, 3}, C[] = {3, 1, 2, 3}Ou
8 min read
Minimum steps to convert one binary string to other only using negation Given two binary strings A and B, the task is to convert A to B by choosing any sub-string of A and negating it (replace each 0 with 1 and each 1 with 0). Print the minimum number of operations required. Examples: Input: A = "101010", B = "110011" Output: 2 Choose the sub-string of length 2 from ind
7 min read