bluecode-园区规划中的最小正方形划分问题

42 阅读2分钟

问题描述

公司购买了一块 m×nm×n 大小的地皮,需要将这块地皮规划为多个正方形区域。为了降低成本,要求划分的正方形区域个数尽量少。你需要帮助公司计算最少需要划分多少个正方形区域,才能完全覆盖这块地皮。

例如,对于一个 3×23×2 的地皮,最少可以划分为3个正方形区域;而对于一个 13×1113×11 的地皮,最少可以划分为6个正方形区域。


测试样例

样例1:

输入:m = 3, n = 2
输出:3

样例2:

输入:m = 13, n = 11
输出:6

样例3:

输入:m = 4, n = 4
输出:1

#include <iostream>
#include <string>
#include <vector>
#include <climits>
#include <functional>

using namespace std;

int solution(int m, int n) {
  // PLEASE DO NOT MODIFY THE FUNCTION SIGNATURE
  // write code here
  vector<vector<bool>> matrix(m + 1, vector<bool>(n + 1, false));
  int ans = INT_MAX;

  // Helper function to check if we can place a square of size len at position
  // (row, col)
  auto check = [&](int row, int col, int len) {
    if (row + len - 1 > m || col + len - 1 > n)
      return false;
    for (int i = 0; i < len; i++) {
      for (int j = 0; j < len; j++) {
        if (matrix[row + i][col + j]) {
          return false;
        }
      }
    }
    return true;
  };

  // Helper function to fill/unfill a square of size len at position (row, col)
  auto fill = [&](int row, int col, int len) {
    for (int i = 0; i < len; i++) {
      for (int j = 0; j < len; j++) {
        matrix[row + i][col + j] = !matrix[row + i][col + j];
      }
    }
  };

  // DFS function to try all possible square placements
  function<void(int, int, int)> dfs = [&](int row, int col, int cnt) {
    if (cnt >= ans)
      return;
    if (row > m) {
      ans = cnt;
      return;
    }
    if (col > n) {
      dfs(row + 1, 1, cnt);
      return;
    }

    bool flag = true;
    for (int j = col; j <= n; j++) {
      if (!matrix[row][j]) {
        flag = false;
        int maxSize = min(m - row + 1, n - j + 1);
        for (int size = maxSize; size >= 1; size--) {
          if (check(row, j, size)) {
            fill(row, j, size);
            dfs(row, j + size, cnt + 1);
            fill(row, j, size); // backtrack
          }
        }
        break;
      }
    }

    if (flag) {
      dfs(row + 1, 1, cnt);
    }
  };

  dfs(1, 1, 0);
  return ans;
}

int main() {
  cout << (solution(3, 2) == 3) << endl;
  cout << (solution(13, 11) == 6) << endl;
  cout << (solution(4, 4) == 1) << endl;
}