CSES Solutions Rectangle Cutting (original) (raw)

Last Updated : 8 Apr, 2024

Given an **A X B rectangle, your task is to cut it into squares. On each move you can select a rectangle and cut it into two rectangles in such a way that all side lengths remain integers. What is the minimum possible number of moves?

**Examples:

**Input: A = 3, B = 5
**Output: 3
**Explanation: The three moves required to cut the rectangle into squares are:

**Input: A = 5, B = 10
**Output: 1
**Explanation: Only 1 move is required to cut the rectangle into squares and that is by cutting the 5 X 10 rectangle into 2 squares of size 5 X 5.

**Approach: To solve the problem, follow the below idea:

Maintain a dp[][] array such that **dp[i][j] stores the minimum number of cuts required to cut an (i X j) rectangle into squares. For an (i X j) rectangle, there can be two cases:

After considering over all the possible cuts, dp[A][B] stores the final answer.

**Step-by-step algorithm:

Below is the implementation of the algorithm:

C++ `

#include <bits/stdc++.h> #define ll long long using namespace std;

// Function to find the minimum number of moves required to // cut a rectangle of A X B into squares ll solve(ll A, ll B) { // dp[][] table such that dp[i][j] stores the minimum // number of cuts required to cut a rectangle of size (i // X j) into squares vector<vector > dp(A + 1, vector(B + 1, 1e9)); for (int i = 0; i <= A; i++) { for (int j = 0; j <= B; j++) { // If the rectangle is already a square, then 0 // cuts are required if (i == j) { dp[i][j] = 0; } else { // Iterate over all the possible cuts we can // make horizontally for (int k = 1; k < j; k++) { dp[i][j] = min(dp[i][j], dp[i][k] + dp[i][j - k] + 1); } // Iterate over all the possible cuts we can // make vertically for (int k = 1; k < i; k++) { dp[i][j] = min(dp[i][j], dp[k][j] + dp[i - k][j] + 1); } } } } // Return the minimum number of cuts required to cut a // rectangle of size (A X B) into squares return dp[A][B]; }

int main() { // Sample Input int A = 3, B = 5;

cout << solve(A, B) << "\n";

}

Java

import java.util.Arrays;

public class RectangleCutting {

// Function to find the minimum number of moves required to
// cut a rectangle of A X B into squares
static long solve(long A, long B) {
    // dp[][] table such that dp[i][j] stores the minimum
    // number of cuts required to cut a rectangle of size (i
    // X j) into squares
    long[][] dp = new long[(int) (A + 1)][(int) (B + 1)];
    for (int i = 0; i <= A; i++) {
        Arrays.fill(dp[i], Integer.MAX_VALUE);
    }
    for (int i = 0; i <= A; i++) {
        for (int j = 0; j <= B; j++) {
            // If the rectangle is already a square, then 0
            // cuts are required
            if (i == j) {
                dp[i][j] = 0;
            } else {
                // Iterate over all the possible cuts we can
                // make horizontally
                for (int k = 1; k < j; k++) {
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[i][j - k] + 1);
                }
                // Iterate over all the possible cuts we can
                // make vertically
                for (int k = 1; k < i; k++) {
                    dp[i][j] = Math.min(dp[i][j], dp[k][j] + dp[i - k][j] + 1);
                }
            }
        }
    }
    // Return the minimum number of cuts required to cut a
    // rectangle of size (A X B) into squares
    return dp[(int) A][(int) B];
}

public static void main(String[] args) {
    // Sample Input
    int A = 3, B = 5;

    System.out.println(solve(A, B));
}

}

// This code is contributed by shivamgupta0987654321

Python3

Function to find the minimum number of moves required to

cut a rectangle of A X B into squares

def solve(A, B): # dp[][] table such that dp[i][j] stores the minimum # number of cuts required to cut a rectangle of size (i # X j) into squares dp = [[float('inf')] * (B + 1) for _ in range(A + 1)]

for i in range(A + 1):
    for j in range(B + 1):
        # If the rectangle is already a square, then 0
        # cuts are required
        if i == j:
            dp[i][j] = 0
        else:
            # Iterate over all the possible cuts we can
            # make horizontally
            for k in range(1, j):
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[i][j - k] + 1)
            # Iterate over all the possible cuts we can
            # make vertically
            for k in range(1, i):
                dp[i][j] = min(dp[i][j], dp[k][j] + dp[i - k][j] + 1)

# Return the minimum number of cuts required to cut a
# rectangle of size (A X B) into squares
return dp[A][B]

Sample Input

A = 3 B = 5 print(solve(A, B))

JavaScript

// Function to find the minimum number of moves required to // cut a rectangle of A X B into squares function solve(A, B) { // Create a dp table such that dp[i][j] stores the minimum // number of cuts required to cut a rectangle of size (i X j) into squares let dp = new Array(A + 1).fill().map(() => new Array(B + 1).fill(Number.MAX_SAFE_INTEGER));

for (let i = 0; i <= A; i++) {
    for (let j = 0; j <= B; j++) {
        // If the rectangle is already a square, then 0 cuts are required
        if (i === j) {
            dp[i][j] = 0;
        } else {
            // Iterate over all the possible cuts we can make horizontally
            for (let k = 1; k < j; k++) {
                dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[i][j - k] + 1);
            }
            // Iterate over all the possible cuts we can make vertically
            for (let k = 1; k < i; k++) {
                dp[i][j] = Math.min(dp[i][j], dp[k][j] + dp[i - k][j] + 1);
            }
        }
    }
}
// Return the minimum number of cuts required to cut a rectangle of size (A X B) into squares
return dp[A][B];

}

// Sample Input let A = 3, B = 5;

console.log(solve(A, B));

`

**Time Complexity: O(A * A * B + A * B * B), where **A and **B are the dimensions of the input rectangle.
**Auxiliary Space: O(A * B)