[LeetCode] Tiling a Rectangle with the Fewest Squares

1240. Tiling a Rectangle with the Fewest Squares

Given a rectangle of size n x m, return the minimum number of integer-sided squares that tile the rectangle.

  • Time : O(nm * min(n,m))
  • Space : O(2^(n+m))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
unordered_map<bitset<169>, int> visit;
bool check(int y, int x, int width, int n, int m, bitset<169> bi) {
if(y + width - 1 >= n) return false;
if(x + width - 1 >= m) return false;
for(int i = x; i < x + width; i++) {
if(bi[i + (y + width - 1) * m]) return false;
}
for(int i = y; i < y + width; i++) {
if(bi[x + width - 1 + i * m]) return false;
}
return true;
}
void change(int y, int x, int width, int m, bitset<169>& bi) {
bi;
for(int i = x; i < x + width; i++) {
bi[i + (y + width - 1) * m] = 1;
}
for(int i = y; i < y + width; i++) {
bi[x + width - 1 + i * m] = 1;
}
return ;
}
int solution(int &n, int &m, bitset<169> bi) {
if(visit.count(bi)) return visit[bi];
int res = INT_MAX;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
int p = j + i * m;
if(bi[p]) continue;
bitset<169> next = bi;
for(int target = 1; target <= min(n,m) and check(i,j,target,n,m,next); target++) {
change(i,j,target,m,next);
res = min(res, solution(n,m, next) + 1);
}
return visit[bi] = res;
}
}
return -1;
}
public:
int tilingRectangle(int n, int m) {
if(n == m) return 1;
if(n == 1 or m == 1) return max(n,m);
bitset<169> bi;
for(int i = 0; i < n*m; i++) {
bi.flip(i);
}
visit[bi] = 0;
for(int i = 0; i < n*m; i++) {
bi.flip(i);
}
return solution(n,m, bi);
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2022/02/14/PS/LeetCode/tiling-a-rectangle-with-the-fewest-squares/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.