Given a rectangular paper with dimensions n × m, find the minimum number of squares that can be formed by cutting the paper. Each cut must be made completely across the remaining paper, either horizontally or vertically.
Examples:
Input: n = 4, m = 5
Output: 5
Explanation: One square of size 4 x 4 and four squares of size 1 x 1 are required.Input: n = 2, m = 4
Output: 2
Explanation: Two squares of size 2 x 2 are enough to fill the rectangle.Input: n = 11, m = 13
Output: 8
Explanation: One square of size 11 x 11, five squares of size 2 x 2, and two squares of size 1 x 1 are formed by following the rule. Please note that if we are allowed to make partial horizontal or vertical cuts, we can have 6 squares which is a different interesting problem, Min Cut Square.
Table of Content
[Naive Approach] Remove One Square at a Time - O(max(n, m)) Time and O(1) Space
If n >= m, the largest square is m × m. Remove it by reducing n by m, and count one square. Repeat until the rectangle is completely divided.
- Initialize res = 0.
- While both n and m are greater than 0, make n the larger dimension by swapping them if necessary.
- Remove one largest possible square of size m × m by setting n = n - m.
- Increment res to count the removed square.
- Repeat until one dimension becomes 0.
#include <bits/stdc++.h>
using namespace std;
// Returns the minimum number of squares required
// to divide an n x m rectangle.
int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0)
{
// Make n the larger dimension.
if (n < m)
swap(n, m);
// Remove one largest possible square of size m x m.
n -= m;
// Count the removed square.
res++;
}
return res;
}
int main()
{
int n = 4, m = 5;
cout << minSquares(n, m) << endl;
return 0;
}
class GFG {
static int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
int temp = n;
n = m;
m = temp;
}
// Remove one largest possible square of size m x m.
n -= m;
// Count the removed square.
res++;
}
return res;
}
public static void main(String[] args)
{
int n = 4, m = 5;
System.out.println(minSquares(n, m));
}
}
# Returns the minimum number of squares required
# to divide an n x m rectangle.
def minSquares(n, m):
res = 0
# Continue until the rectangle becomes empty.
while n > 0 and m > 0:
# Make n the larger dimension.
if n < m:
n, m = m, n
# Remove one largest possible square of size m x m.
n -= m
# Count the removed square.
res += 1
return res
# Driver Code
if __name__ == "__main__":
n = 4
m = 5
print(minSquares(n, m))
using System;
class GFG {
static int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
int temp = n;
n = m;
m = temp;
}
// Remove one largest possible square of size m x m.
n -= m;
// Count the removed square.
res++;
}
return res;
}
static void Main()
{
int n = 4, m = 5;
Console.WriteLine(minSquares(n, m));
}
}
// Returns the minimum number of squares required
// to divide an n x m rectangle.
function minSquares(n, m)
{
let res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
[n, m] = [ m, n ];
}
// Remove one largest possible square of size m x m.
n -= m;
// Count the removed square.
res++;
}
return res;
}
// Driver Code
let n = 4, m = 5;
console.log(minSquares(n, m));
Output
5
[Expected Approach] Optimized Euclidean Algorithm - O(log(min(n, m))) Time and O(1) Space
This process is exactly the Euclidean algorithm.
When n >= m, we can directly remove all possible m × m squares. There are n / m such squares, and the remaining rectangle has dimensions m × (n % m).
- Initialize res = 0.
- While n > 0 and m > 0, make n the larger dimension.
- Add n / m to res, representing all possible m × m squares.
- Set n = n % m to obtain the remaining rectangle.
- Repeat until one dimension becomes 0.
#include <bits/stdc++.h>
using namespace std;
// Returns the minimum number of squares required
// to divide an n x m rectangle.
int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0)
{
// Make n the larger dimension.
if (n < m)
swap(n, m);
// Count all possible squares of size m x m.
res += n / m;
// Keep the remaining rectangle.
n %= m;
}
return res;
}
int main()
{
int n = 4, m = 5;
cout << minSquares(n, m) << endl;
return 0;
}
class GFG {
static int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
int temp = n;
n = m;
m = temp;
}
// Count all possible squares of size m x m.
res += n / m;
// Keep the remaining rectangle.
n %= m;
}
return res;
}
public static void main(String[] args)
{
int n = 4, m = 5;
System.out.println(minSquares(n, m));
}
}
# Returns the minimum number of squares required
# to divide an n x m rectangle.
def minSquares(n, m):
res = 0
# Continue until the rectangle becomes empty.
while n > 0 and m > 0:
# Make n the larger dimension.
if n < m:
n, m = m, n
# Count all possible squares of size m x m.
res += n // m
# Keep the remaining rectangle.
n %= m
return res
# Driver Code
if __name__ == "__main__":
n = 4
m = 5
print(minSquares(n, m))
using System;
class GFG {
static int minSquares(int n, int m)
{
int res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
int temp = n;
n = m;
m = temp;
}
// Count all possible squares of size m x m.
res += n / m;
// Keep the remaining rectangle.
n %= m;
}
return res;
}
static void Main()
{
int n = 4, m = 5;
Console.WriteLine(minSquares(n, m));
}
}
// Returns the minimum number of squares required
// to divide an n x m rectangle.
function minSquares(n, m)
{
let res = 0;
// Continue until the rectangle becomes empty.
while (n > 0 && m > 0) {
// Make n the larger dimension.
if (n < m) {
[n, m] = [ m, n ];
}
// Count all possible squares of size m x m.
res += Math.floor(n / m);
// Keep the remaining rectangle.
n %= m;
}
return res;
}
// Driver Code
let n = 4, m = 5;
console.log(minSquares(n, m));
Output
5