Open In App

Minimum number of sub-strings of a string such that all are power of 5

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string str. The task is to find the smallest positive integer C such that the binary string can be cut into C pieces (sub-strings) and each sub-string should be a power of 5 with no leading zeros.
Examples: 
 

Input: str = “101101101” 
Output:
The string “101101101” can be cut into three binary strings “101”, “101”, “101” 
each of which is a power of 5.
Input: str = “1111101” 
Output:
The string “1111101” can be cut into one binary string “1111101” which is 
125 in decimal and a power of 5.
Input: str = “00000” 
Output: -1 
Strings of only zeroes is equivalent to 0 which is not a power of 5. 
 

 

Approach: This problem is a simple variation of the longest increasing sub-sequence
Iterate from i = 1 and for every str[j…i] where j = 0 & j < i, we check if the number formed from str[j..i] is a power of 5 then we update the dp[] array with the value of the lowest possible cut size value. After confirming that the number formed from str[j..i] in decimal is a power of 5 we calculate dp[i] = min(dp[i], dp[j] + 1)
This technique is pretty similar to finding the longest increasing sub-sequence.
Below is the implementation of the above approach: 
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
 
// Function that returns true
// if n is a power of 5
bool ispower(ll n)
{
    if (n < 125)
        return (n == 1 || n == 5 || n == 25);
    if (n % 125 != 0)
        return false;
    else
        return ispower(n / 125);
}
 
// Function to return the decimal
// value of binary equivalent
ll number(string s, int i, int j)
{
    ll ans = 0;
    for (int x = i; x < j; x++) {
        ans = ans * 2 + (s[x] - '0');
    }
    return ans;
}
 
// Function to return the minimum cuts required
int minCuts(string s, int n)
{
    int dp[n + 1];
 
    // Allocating memory for dp[] array
    memset(dp, n + 1, sizeof(dp));
    dp[0] = 0;
 
    // From length 1 to n
    for (int i = 1; i <= n; i++) {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if (s[i - 1] == '0')
            continue;
        for (int j = 0; j < i; j++) {
 
            // Ignore s[j] = '0' starting numbers
            if (s[j] == '0')
                continue;
 
            // Number formed from s[j....i]
            ll num = number(s, j, i);
 
            // Check for power of 5
            if (!ispower(num))
                continue;
 
            // Assigning min value to get min cut possible
            dp[i] = min(dp[i], dp[j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return ((dp[n] < n + 1) ? dp[n] : -1);
}
 
// Driver code
int main()
{
    string s = "101101101";
    int n = s.length();
    cout << minCuts(s, n);
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Function that returns true
    // if n is a power of 5
    static boolean ispower(long n)
    {
        if (n < 125)
        {
            return (n == 1 || n == 5 || n == 25);
        }
        if (n % 125 != 0)
        {
            return false;
        }
        else
        {
            return ispower(n / 125);
        }
    }
 
    // Function to return the decimal
    // value of binary equivalent
    static long number(String s, int i, int j)
    {
        long ans = 0;
        for (int x = i; x < j; x++)
        {
            ans = ans * 2 + (s.charAt(x) - '0');
        }
        return ans;
    }
 
    // Function to return the minimum cuts required
    static int minCuts(String s, int n)
    {
        int[] dp = new int[n + 1];
 
        // Alongocating memory for dp[] array
        Arrays.fill(dp, n+1);
        dp[0] = 0;
 
        // From length 1 to n
        for (int i = 1; i <= n; i++)
        {
 
            // If previous character is '0' then ignore
            // to avoid number with leading 0s.
            if (s.charAt(i - 1) == '0')
            {
                continue;
            }
            for (int j = 0; j < i; j++)
            {
 
                // Ignore s[j] = '0' starting numbers
                if (s.charAt(j) == '0')
                {
                    continue;
                }
 
                // Number formed from s[j....i]
                long num = number(s, j, i);
 
                // Check for power of 5
                if (!ispower(num))
                {
                    continue;
                }
 
                // Assigning min value to get min cut possible
                dp[i] = Math.min(dp[i], dp[j] + 1);
            }
        }
 
        // (n + 1) to check if all the Strings are traversed
        // and no divisible by 5 is obtained like 000000
        return ((dp[n] < n + 1) ? dp[n] : -1);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String s = "101101101";
        int n = s.length();
        System.out.println(minCuts(s, n));
    }
}
 
// This code is contributed by 29AjayKumar


Python 3




# Python 3 implementation of the approach
  
# Function that returns true
# if n is a power of 5
def ispower( n):
    if (n < 125):
        return (n == 1 or n == 5 or n == 25)
    if (n % 125 != 0):
        return 0
    else:
        return ispower(n // 125)
 
  
# Function to return the decimal
# value of binary equivalent
def number(s, i, j):
    ans = 0
    for x in range( i, j) :
        ans = ans * 2 + (ord(s[x]) - ord('0'))
    return ans
 
# Function to return the minimum cuts required
def minCuts(s, n):
  
    # Allocating memory for dp[] array
    dp=[n+1 for i in range(n+1)]
    dp[0] = 0;
  
    # From length 1 to n
    for i in range(1, n+1) :
  
        # If previous character is '0' then ignore
        # to avoid number with leading 0s.
        if (s[i - 1] == '0'):
            continue
        for j in range(i) :
  
            # Ignore s[j] = '0' starting numbers
            if (s[j] == '0'):
                continue
  
            # Number formed from s[j....i]
            num = number(s, j, i)
  
            # Check for power of 5
            if (not ispower(num)):
                continue
  
            # Assigning min value to get min cut possible
            dp[i] = min(dp[i], dp[j] + 1)
  
    # (n + 1) to check if all the strings are traversed
    # and no divisible by 5 is obtained like 000000
    if dp[n] < n + 1:
        return dp[n]
    else:
        return  -1
  
# Driver code
if __name__== "__main__":
    s = "101101101"
    n = len(s)
    print(minCuts(s, n))
 
# This code is contributed by ChitraNayal


C#




// C# implementation of the approach
using System;
 
class GFG
{
 
    // Function that returns true
    // if n is a power of 5
    static Boolean ispower(long n)
    {
        if (n < 125)
        {
            return (n == 1 || n == 5 || n == 25);
        }
        if (n % 125 != 0)
        {
            return false;
        }
        else
        {
            return ispower(n / 125);
        }
    }
 
    // Function to return the decimal
    // value of binary equivalent
    static long number(String s, int i, int j)
    {
        long ans = 0;
        for (int x = i; x < j; x++)
        {
            ans = ans * 2 + (s[x] - '0');
        }
        return ans;
    }
 
    // Function to return the minimum cuts required
    static int minCuts(String s, int n)
    {
        int[] dp = new int[n + 1];
 
        // Alongocating memory for dp[] array
        for (int i = 0; i <= n; i++)
            dp[i]=n+1;
        dp[0] = 0;
 
        // From length 1 to n
        for (int i = 1; i <= n; i++)
        {
 
            // If previous character is '0' then ignore
            // to avoid number with leading 0s.
            if (s[i - 1] == '0')
            {
                continue;
            }
            for (int j = 0; j < i; j++)
            {
 
                // Ignore s[j] = '0' starting numbers
                if (s[j] == '0')
                {
                    continue;
                }
 
                // Number formed from s[j....i]
                long num = number(s, j, i);
 
                // Check for power of 5
                if (!ispower(num))
                {
                    continue;
                }
 
                // Assigning min value to get min cut possible
                dp[i] = Math.Min(dp[i], dp[j] + 1);
            }
        }
 
        // (n + 1) to check if all the Strings are traversed
        // and no divisible by 5 is obtained like 000000
        return ((dp[n] < n + 1) ? dp[n] : -1);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        String s = "101101101";
        int n = s.Length;
        Console.WriteLine(minCuts(s, n));
    }
}
 
/* This code contributed by PrinciRaj1992 */


PHP




<?php
// PHP implementation of the approach
 
// Function that returns true
// if n is a power of 5
function ispower($n)
{
    if ($n < 125)
        return ($n == 1 || $n == 5 || $n == 25);
    if ($n % 125 != 0)
        return false;
    else
        return ispower($n / 125);
}
 
// Function to return the decimal
// value of binary equivalent
function number($s, $i, $j)
{
    $ans = 0;
    for ($x = $i; $x < $j; $x++)
    {
        $ans = $ans * 2 + (ord($s[$x]) - ord('0'));
    }
    return $ans;
}
 
// Function to return the minimum cuts required
function minCuts($s, $n)
{
    // Allocating memory for dp[] array
    $dp = array_fill(0,$n + 1,$n + 1);
     
    $dp[0] = 0;
 
    // From length 1 to n
    for ($i = 1; $i <= $n; $i++)
    {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if ($s[$i - 1] == '0')
            continue;
        for ($j = 0; $j < $i; $j++)
        {
 
            // Ignore s[j] = '0' starting numbers
            if ($s[$j] == '0')
                continue;
 
            // Number formed from s[j....i]
            $num = number($s, $j, $i);
 
            // Check for power of 5
            if (!ispower($num))
                continue;
 
            // Assigning min value to get min cut possible
            $dp[$i] = min($dp[$i], $dp[$j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return (($dp[$n] < $n + 1) ? $dp[$n] : -1);
}
 
    // Driver code
    $s = "101101101";
    $n = strlen($s);
    echo minCuts($s, $n);
 
    // This code is contributed by AnkitRai01
 
?>


Javascript




<script>
 
// Javascript implementation of the approach
 
// Function that returns true
// if n is a power of 5
function ispower(n)
{
    if (n < 125)
        return (n == 1 || n == 5 || n == 25);
    if (n % 125 != 0)
        return false;
    else
        return ispower(parseInt(n / 125));
}
 
// Function to return the decimal
// value of binary equivalent
function number(s, i, j)
{
    var ans = 0;
    for (var x = i; x < j; x++) {
        ans = ans * 2 + (s[x] - '0');
    }
    return ans;
}
 
// Function to return the minimum cuts required
function minCuts(s, n)
{
    var dp = Array(n+1).fill(n+1);
    dp[0] = 0;
 
    // From length 1 to n
    for (var i = 1; i <= n; i++) {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if (s[i - 1] == '0')
            continue;
        for (var j = 0; j < i; j++) {
 
            // Ignore s[j] = '0' starting numbers
            if (s[j] == '0')
                continue;
 
            // Number formed from s[j....i]
            var num = number(s, j, i);
 
            // Check for power of 5
            if (!ispower(num))
                continue;
 
            // Assigning min value to get min cut possible
            dp[i] = Math.min(dp[i], dp[j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return ((dp[n] < n + 1) ? dp[n] : -1);
}
 
// Driver code
var s = "101101101";
var n = s.length;
document.write( minCuts(s, n));
 
</script>


Output: 

3

 

Time complexity: O(n2
Space complexity: O(n)
 



Last Updated : 28 May, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads