Dada una string binaria S de longitud N , la tarea es minimizar el número de operaciones necesarias para encontrar una string binaria T de la misma longitud N tal que:
- En una sola operación, se permite voltear cualquier bit , es decir, convertir 0 a 1 o viceversa.
- En la string binaria T , elija un número K , tal que:
- N es perfectamente divisible por K , y
- Los primeros K bits en T son 0 , los siguientes K son 1 , los siguientes K son 0 , y así sucesivamente.
Ejemplos:
Entrada: S = 1011011
Salida: 4
Explicación:
Si elegimos K = 1, entonces la string requerida S=0101010, Movimientos requeridos 4
Si elegimos K = 7, entonces la string requerida S=0000000, Movimientos requeridos 5
Valores de K= 2, 3, 4, 5, 6 no está permitido porque no se divide perfectamente N = 7.
Elija K = 1. Entonces, la string final es 0101010, invierta el primer, segundo, tercer y séptimo bit. Imprime 4 porque la string S satisface todas las condiciones después de realizar 4 movimientos.Entrada: S = 000001
Salida: 1
Explicación:
Si elegimos K=1, entonces la string requerida S=010101, Movimientos requeridos 2
Si elegimos K=2, entonces la string requerida S=001100, Movimientos requeridos 3
Si elegimos K=3 , entonces string requerida S=000111, Movimientos requeridos 2
Si elegimos K=6, entonces string requerida S=000000, Movimientos requeridos 1
Entonces, Seleccione K=6, Entonces, la salida será 1.
Enfoque: El enfoque se basa en la siguiente observación:
En el enunciado del problema se menciona que tenemos que elegir K tal que N sea divisible por K, de modo que podamos dividir nuestro problema en subproblemas para encontrar todos los divisores de N y luego encontrar el número de operaciones requeridas para cada uno de los divisores y elegir el número mínimo de operación entre todos ellos.
Con base en la observación anterior, siga los pasos a continuación para implementar este enfoque:
- Encuentre todos los divisores de N (tamaño de la string dada).
- Para cada divisor, Traverse the String y para cada iteración:
- Cuente el número de cambios requeridos en la string dada si elegimos el K = divisor actual.
- Si los cambios actuales requeridos son menores que el resultado anterior, actualícelo con el resultado actual.
- Devolver los cambios mínimos requeridos.
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ code to implement above approach #include <bits/stdc++.h> using namespace std; // Function to find all divisors // of given string length n. void findAllDivisors(int n, vector<int>& v) { for (int i = 1; i <= sqrt(n); i++) { // Check whether the given number // is divisible by current number or not if (n % i == 0) { // Check if divisors are equal if (n / i == i) v.push_back(i); else { v.push_back(n / i); } } } } // Function to find the minimum // number of operation require to make // given substring alternative of size K int findMinOperations(string& S) { int n = S.length(), result = n; // Find and store all divisors of n. vector<int> v; findAllDivisors(n, v); // For each divisor, // calculate minimum changes required. for (int i = 0; i < v.size(); i++) { // Count of operations required int count = 0; bool flag = false; for (int j = 0; j < n; j += v[i]) { for (int k = j; k < j + v[i] && k < n; k++) { if (flag && S[k] == '0') count++; if (!flag && S[k] == '1') count++; } flag = (flag == false); } // If current changes required // is less than previous result // then update result if (count < result) result = count; } return result; } // Driver code int main() { string S = "101101"; cout << findMinOperations(S); return 0; }
Java
// Java code to implement above approach import java.util.*; class GFG { // Function to find all divisors // of given string length n. static void findAllDivisors(int n, Vector<Integer> v) { for (int i = 1; i <= Math.sqrt(n); i++) { // Check whether the given number // is divisible by current number or not if (n % i == 0) { // Check if divisors are equal if (n / i == i) v.add(i); else { v.add(n / i); } } } } // Function to find the minimum // number of operation require to make // given substring alternative of size K static int findMinOperations(String S) { int n = S.length(); int result = n; // Find and store all divisors of n. Vector<Integer> v = new Vector<Integer>(); findAllDivisors(n, v); // For each divisor, // calculate minimum changes required. for (int i = 0; i < v.size(); i++) { // Count of operations required int count = 0; boolean flag = false; for (int j = 0; j < n; j += v.get(i)) { for (int k = j; k < j + v.get(i) && k < n; k++) { if (flag && S.charAt(k) == '0') count++; if (!flag && S.charAt(k) == '1') count++; } flag = (flag == false); } // If current changes required // is less than previous result // then update result if (count < result) result = count; } return result; } // Driver code public static void main(String[] args) { String S = "101101"; System.out.print(findMinOperations(S)); } } // This code is contributed by hrithikgarg03188.
Python3
# Python3 program to implement the above approach # function to find all divisors of # given string length n def findAllDivisors(n, v): for i in range(1, 1 + int(n ** 0.5)): # check whether the given number # is divisible by the current number or not if n % i == 0: # check if divisors are equal if (n // i) == i: v.append(i) else: v.append(n // i) return v # function to find the minimum # number of opertations required to make # given substring alternative of size K def findMinOperations(S): n = len(S) result = n # find and store all divisors of n v = [] v = findAllDivisors(n, v) for i in range(len(v)): # count of operations required count = 0 flag = False for j in range(0, n, v[i]): for k in range(j, min(j + v[i], n), 1): if (flag and S[k]) == "0": count += 1 if (not flag and S[k]) == "1": count += 1 flag = bool(flag == False) # if current changes required # is less than the previous result, # then, update the result if count < result: result = count return result # Driver Code S = "101101" print(findMinOperations(S)) # this code was contributed by phasing17
C#
// C# code to implement above approach using System; using System.Collections; public class GFG{ // Function to find all divisors // of given string length n. static void findAllDivisors(int n, ArrayList v) { for (int i = 1; i <= Math.Sqrt(n); i++) { // Check whether the given number // is divisible by current number or not if (n % i == 0) { // Check if divisors are equal if (n / i == i) v.Add(i); else { v.Add(n / i); } } } } // Function to find the minimum // number of operation require to make // given substring alternative of size K static int findMinOperations(String S) { int n = S.Length; int result = n; // Find and store all divisors of n. ArrayList v = new ArrayList(); findAllDivisors(n, v); // For each divisor, // calculate minimum changes required. for (int i = 0; i < v.Count; i++) { // Count of operations required int count = 0; bool flag = false; for (int j = 0; j < n; j += (int)v[i]) { for (int k = j; k < j + (int)v[i] && k < n; k++) { if (flag && S[k] == '0') count++; if (!flag && S[k] == '1') count++; } flag = (flag == false); } // If current changes required // is less than previous result // then update result if (count < result) result = count; } return result; } // Driver code static public void Main (){ string S = "101101"; Console.Write(findMinOperations(S)); } } // This code is contributed by hrithikgarg03188.
Javascript
// JavaScript code to implement above approach // Function to find all divisors // of given string length n. function findAllDivisors(n, v) { for (var i = 1; i <= Math.floor(Math.sqrt(n)); i++) { // Check whether the given number // is divisible by current number or not if (n % i == 0) { // Check if divisors are equal if (Math.floor(n / i) == i) v.push(i); else { v.push(Math.floor(n / i)); } } } return v; } // Function to find the minimum // number of operation require to make // given substring alternative of size K function findMinOperations(S) { var n = S.length; var result = n; // Find and store all divisors of n. var v = []; v = findAllDivisors(n, v); // For each divisor, // calculate minimum changes required. for (var i = 0; i < v.length; i++) { // Count of operations required var count = 0; var flag = false; for (var j = 0; j < n; j += v[i]) { for (var k = j; k < j + v[i] && k < n; k++) { if (flag && S[k] == '0') count++; if (!flag && S[k] == '1') count++; } flag = (flag == false); } // If current changes required // is less than previous result // then update result if (count < result) result = count; } return result; } // Driver code var S = "101101"; document.write(findMinOperations(S)); //This code is contributed by phasing17
3
Complejidad de tiempo: O(N*sqrt(N)), O(sqrt(N)) para encontrar todos los divisores y O(N) para encontrar todas las operaciones para cada divisor.
Espacio auxiliar: O(sqrt(N)), para almacenar todos los divisores.
Publicación traducida automáticamente
Artículo escrito por khatriharsh281 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA