Minimum tiles of sizes in powers of two to cover whole area

Last Updated : 25 May, 2022

Given an area of N X M. You have the infinite number of tiles of size 2i X 2i, where i = 0, 1, 2,... so on. The task is to find the minimum number of tiles required to fill the given area with tiles.
Examples: 
 

Input : N = 5, M = 6.
Output : 9
Area of 5 X 6 can be covered with minimum 9 tiles.
6 tiles of 1 X 1, 2 tiles of 2 X 2, 1 tile of 4 X 4.

Input : N = 10, M = 5.
Output : 14

The idea is to divide the given area into the nearest 2i X 2i
Let's divide the problem into cases: 
Case 1: if N is odd and M is even, fill the row or column with M number of 1 X 1 tiles. Then count the minimum number of tiles for N/2 X M/2 size of the area. Similarly, if M is odd and N is even, add N to our answer and find a minimum number of tiles for the N/2 X M/2 area.
Case 2: If N and M both are odd, fill one row and one column, so add N + M - 1 to the answer and find the minimum number of tiles required to fill the N/2 X M/2 area.
Case 3: If N and M both are even, calculate the minimum number of tiles required to fill the area with N/2 X M/2 area. Because halving both the dimensions doesn't change the number of tiles required.
Below is the implementation of this approach: 
 

C++
#include<bits/stdc++.h>
using namespace std;

int minTiles(int n, int m)
{
  // base case, when area is 0.
  if (n == 0 || m == 0)
    return 0;

  // If n and m both are even, calculate tiles for n/2 x m/2
  // Halving both dimensions doesn't change the number of tiles
  else if (n%2 == 0 && m%2 == 0)
    return minTiles(n/2, m/2);
  
  // If n is even and m is odd
  // Use a row of 1x1 tiles
  else if (n%2 == 0 && m%2 == 1)
    return (n + minTiles(n/2, m/2));

  // If n is odd and m is even
  // Use a column of 1x1 tiles
  else if (n%2 == 1 && m%2 == 0)
    return (m + minTiles(n/2, m/2));

  // If n and m are odd
  // add row + column number of tiles
  else
    return (n + m - 1 + minTiles(n/2, m/2)); 
}

// Driven Program
int main()
{
  int n = 5, m = 6;

  cout << minTiles(n, m) << endl;
  return 0;
}
Java
// Java code for Minimum tiles of 
// sizes in powers of two to cover 
// whole area

class GFG {
    
    static int minTiles(int n, int m)
    {
    // base case, when area is 0.
    if (n == 0 || m == 0)
        return 0;
    
    // If n and m both are even, 
    // calculate tiles for n/2 x m/2
    // Halving both dimensions doesn't 
    // change the number of tiles
    else if (n % 2  == 0 && m % 2 == 0)
        return minTiles(n / 2, m / 2);
        
    // If n is even and m is odd
    // Use a row of 1x1 tiles
    else if (n % 2 == 0 && m % 2 == 1)
        return (n + minTiles(n / 2, m / 2));
    
    // If n is odd and m is even
    // Use a column of 1x1 tiles
    else if (n % 2 == 1 && m % 2 == 0)
        return (m + minTiles(n / 2, m / 2));
    
    // If n and m are odd
    // add row + column number of tiles
    else
        return (n + m - 1 + minTiles(n / 2, m / 2)); 
    }
        
    // Driver code
    public static void main (String[] args)
    {
            int n = 5, m = 6;
            System.out.println(minTiles(n, m));
    }
}

// This code is contributed by Anant Agarwal.
Python3
def minTiles(n, m):
    
    # base case, when area is 0.
    if n == 0 or m == 0:
        return 0

    # If n and m both are even, calculate
    # tiles for n/2 x m/2
    # Halving both dimensions doesn't
    # change the number of tiles
    elif n%2 == 0 and m%2 == 0:
        return minTiles(int(n/2), int(m/2))

    # If n is even and m is odd
    # Use a row of 1x1 tiles
    elif n % 2 == 0 and m % 2 == 1:
        return (n + minTiles(int(n/2), int(m/2)))

    # If n is odd and m is even
    # Use a column of 1x1 tiles
    elif n % 2 == 1 and m % 2 == 0:
        return (m + minTiles(int(n/2), int(m/2)))

    # If n and m are odd add
    # row + column number of tiles
    else:
        return (n + m - 1 + minTiles(int(n/2), int(m/2))) 

# Driven Program
n = 5
m = 6
print (minTiles(n, m))

# This code is contributed
# by Shreyanshi Arun.
C#
// C# code for Minimum tiles of
// sizes in powers of two to cover
// whole area
using System;

class GFG {

    static int minTiles(int n, int m)
    {
        
        // base case, when area is 0.
        if (n == 0 || m == 0)
            return 0;

        // If n and m both are even,
        // calculate tiles for n/2 x m/2
        // Halving both dimensions doesn't
        // change the number of tiles
        else if (n % 2 == 0 && m % 2 == 0)
            return minTiles(n / 2, m / 2);

        // If n is even and m is odd
        // Use a row of 1x1 tiles
        else if (n % 2 == 0 && m % 2 == 1)
            return (n + minTiles(n / 2, m / 2));

        // If n is odd and m is even
        // Use a column of 1x1 tiles
        else if (n % 2 == 1 && m % 2 == 0)
            return (m + minTiles(n / 2, m / 2));

        // If n and m are odd
        // add row + column number of tiles
        else
            return (n + m - 1 + minTiles(n / 2, m / 2));
    }

    // Driver code
    public static void Main()
    {
        int n = 5, m = 6;
        
        Console.WriteLine(minTiles(n, m));
    }
}

// This code is contributed by vt_m.
PHP
<?php
// PHP program for Minimum tiles of 
// sizes in powers of two to cover
// whole area

function minTiles($n, $m)
{
    
    // base case, when area is 0.
    if ($n == 0 or $m == 0)
        return 0;
    
    // If n and m both are even,
    // calculate tiles for n/2 x m/2
    // Halving both dimensions doesn't 
    // change the number of tiles
    else if ($n % 2 == 0 and
                $m % 2 == 0)
        return minTiles($n / 2, $m / 2);
    
    // If n is even and m is odd
    // Use a row of 1x1 tiles
    else if ($n % 2 == 0 and $m % 2 == 1)
        return floor($n + minTiles($n / 2,
                                   $m / 2));
    
    // If n is odd and m is even
    // Use a column of 1x1 tiles
    else if ($n % 2 == 1 and
             $m % 2 == 0)
        return ($m + minTiles($n / 2, 
                              $m / 2));
    
    // If n and m are odd
    // add row + column number of tiles
    else
        return floor($n + $m - 1 + 
                    minTiles($n / 2, $m / 2)); 
}

// Driver Code
$n = 5; $m = 6;
echo minTiles($n, $m);

// This code is contributed by anuj_67.
?>
JavaScript
<script>
// JavaScript code for Minimum tiles of 
// sizes in powers of two to cover 
// whole area

    function minTiles(n, m)
    {
    // base case, when area is 0.
    if (n == 0 || m == 0)
        return 0;
    
    // If n and m both are even, 
    // calculate tiles for n/2 x m/2
    // Halving both dimensions doesn't 
    // change the number of tiles
    else if (n % 2  == 0 && m % 2 == 0)
        return minTiles((n / 2),(m / 2));
        
    // If n is even and m is odd
    // Use a row of 1x1 tiles
    else if (n % 2 == 0 && m % 2 == 1)
        return (n + minTiles(Math.floor(n / 2), Math.floor(m / 2)));
    
    // If n is odd and m is even
    // Use a column of 1x1 tiles
    else if (n % 2 == 1 && m % 2 == 0)
        return (m + minTiles(Math.floor(n / 2), Math.floor(m / 2)));
    
    // If n and m are odd
    // add row + column number of tiles
    else
        return (n + m - 1 + minTiles(Math.floor(n / 2), Math.floor(m / 2))); 
    }

// Driver Code

    let n = 5, m = 6;
    document.write(Math.floor(minTiles(n, m)));
        
</script>

Output:  

9


Complexity Analysis:

Time Complexity: O(log(min(n,m))/log(2)), where n and m are dimensions of tiles. 

Auxiliary Space: O(log(min(n,m))/log(2)), because we are adding an element to the stack during each recursion call.


 

Comment