Skip to content

Commit 30c5674

Browse files
committed
feat: add solutions to lc problem: No.1240
No.1240.Tiling a Rectangle with the Fewest Squares
1 parent 1375737 commit 30c5674

File tree

6 files changed

+632
-1
lines changed

6 files changed

+632
-1
lines changed

Diff for: solution/1200-1299/1240.Tiling a Rectangle with the Fewest Squares/README.md

+218-1
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,239 @@
5555

5656
<!-- 这里可写通用的实现逻辑 -->
5757

58+
**方法一:递归回溯 + 状态压缩**
59+
60+
我们可以按位置进行递归回溯。如果当前位置 $(i, j)$ 已经被填充,则直接递归到下一个位置 $(i, j + 1)$。否则,我们枚举当前位置 $(i, j)$ 可以填充的最大正方形的边长 $w$,并将当前位置 $(i, j)$ 到 $(i + w - 1, j + w - 1)$ 的位置全部填充,然后递归到下一个位置 $(i, j + w)$。在回溯时,我们需要将当前位置 $(i, j)$ 到 $(i + w - 1, j + w - 1)$ 的位置全部清空。
61+
62+
由于每个位置只有两种状态:填充或者未填充,因此我们可以使用一个整数来表示当前位置的状态。我们使用一个长度为 $n$ 的整数数组 `filled`,其中 `filled[i]` 表示第 $i$ 行的状态。如果 `filled[i]` 的第 $j$ 位为 $1$,则表示第 $i$ 行第 $j$ 列已经被填充,否则表示未填充。
63+
5864
<!-- tabs:start -->
5965

6066
### **Python3**
6167

6268
<!-- 这里可写当前语言的特殊实现逻辑 -->
6369

6470
```python
65-
71+
class Solution:
72+
def tilingRectangle(self, n: int, m: int) -> int:
73+
def dfs(i, j, t):
74+
nonlocal ans
75+
if j == m:
76+
i += 1
77+
j = 0
78+
if i == n:
79+
ans = t
80+
return
81+
if filled[i] >> j & 1:
82+
dfs(i, j + 1, t)
83+
elif t + 1 < ans:
84+
r = c = 0
85+
for k in range(i, n):
86+
if filled[k] >> j & 1:
87+
break
88+
r += 1
89+
for k in range(j, m):
90+
if filled[i] >> k & 1:
91+
break
92+
c += 1
93+
mx = r if r < c else c
94+
for w in range(1, mx + 1):
95+
for k in range(w):
96+
filled[i + w - 1] |= 1 << (j + k)
97+
filled[i + k] |= 1 << (j + w - 1)
98+
dfs(i, j + w, t + 1)
99+
for x in range(i, i + mx):
100+
for y in range(j, j + mx):
101+
filled[x] ^= 1 << y
102+
103+
ans = n * m
104+
filled = [0] * n
105+
dfs(0, 0, 0)
106+
return ans
66107
```
67108

68109
### **Java**
69110

70111
<!-- 这里可写当前语言的特殊实现逻辑 -->
71112

72113
```java
114+
class Solution {
115+
private int n;
116+
private int m;
117+
private int[] filled;
118+
private int ans;
119+
120+
public int tilingRectangle(int n, int m) {
121+
this.n = n;
122+
this.m = m;
123+
ans = n * m;
124+
filled = new int[n];
125+
dfs(0, 0, 0);
126+
return ans;
127+
}
128+
129+
private void dfs(int i, int j, int t) {
130+
if (j == m) {
131+
++i;
132+
j = 0;
133+
}
134+
if (i == n) {
135+
ans = t;
136+
return;
137+
}
138+
if ((filled[i] >> j & 1) == 1) {
139+
dfs(i, j + 1, t);
140+
} else if (t + 1 < ans) {
141+
int r = 0, c = 0;
142+
for (int k = i; k < n; ++k) {
143+
if ((filled[k] >> j & 1) == 1) {
144+
break;
145+
}
146+
++r;
147+
}
148+
for (int k = j; k < m; ++k) {
149+
if ((filled[i] >> k & 1) == 1) {
150+
break;
151+
}
152+
++c;
153+
}
154+
int mx = Math.min(r, c);
155+
for (int w = 1; w <= mx; ++w) {
156+
for (int k = 0; k < w; ++k) {
157+
filled[i + w - 1] |= 1 << (j + k);
158+
filled[i + k] |= 1 << (j + w - 1);
159+
}
160+
dfs(i, j + w, t + 1);
161+
}
162+
for (int x = i; x < i + mx; ++x) {
163+
for (int y = j; y < j + mx; ++y) {
164+
filled[x] ^= 1 << y;
165+
}
166+
}
167+
}
168+
}
169+
}
170+
```
171+
172+
### **C++**
173+
174+
```cpp
175+
class Solution {
176+
public:
177+
int tilingRectangle(int n, int m) {
178+
memset(filled, 0, sizeof(filled));
179+
this->n = n;
180+
this->m = m;
181+
ans = n * m;
182+
dfs(0, 0, 0);
183+
return ans;
184+
}
185+
186+
private:
187+
int filled[13];
188+
int n, m;
189+
int ans;
190+
191+
void dfs(int i, int j, int t) {
192+
if (j == m) {
193+
++i;
194+
j = 0;
195+
}
196+
if (i == n) {
197+
ans = t;
198+
return;
199+
}
200+
if (filled[i] >> j & 1) {
201+
dfs(i, j + 1, t);
202+
} else if (t + 1 < ans) {
203+
int r = 0, c = 0;
204+
for (int k = i; k < n; ++k) {
205+
if (filled[k] >> j & 1) {
206+
break;
207+
}
208+
++r;
209+
}
210+
for (int k = j; k < m; ++k) {
211+
if (filled[i] >> k & 1) {
212+
break;
213+
}
214+
++c;
215+
}
216+
int mx = min(r, c);
217+
for (int w = 1; w <= mx; ++w) {
218+
for (int k = 0; k < w; ++k) {
219+
filled[i + w - 1] |= 1 << (j + k);
220+
filled[i + k] |= 1 << (j + w - 1);
221+
}
222+
dfs(i, j + w, t + 1);
223+
}
224+
for (int x = i; x < i + mx; ++x) {
225+
for (int y = j; y < j + mx; ++y) {
226+
filled[x] ^= 1 << y;
227+
}
228+
}
229+
}
230+
}
231+
};
232+
```
73233

234+
### **Go**
235+
236+
```go
237+
func tilingRectangle(n int, m int) int {
238+
ans := n * m
239+
filled := make([]int, n)
240+
var dfs func(i, j, t int)
241+
dfs = func(i, j, t int) {
242+
if j == m {
243+
i++
244+
j = 0
245+
}
246+
if i == n {
247+
ans = t
248+
return
249+
}
250+
if filled[i]>>j&1 == 1 {
251+
dfs(i, j+1, t)
252+
} else if t+1 < ans {
253+
var r, c int
254+
for k := i; k < n; k++ {
255+
if filled[k]>>j&1 == 1 {
256+
break
257+
}
258+
r++
259+
}
260+
for k := j; k < m; k++ {
261+
if filled[i]>>k&1 == 1 {
262+
break
263+
}
264+
c++
265+
}
266+
mx := min(r, c)
267+
for w := 1; w <= mx; w++ {
268+
for k := 0; k < w; k++ {
269+
filled[i+w-1] |= 1 << (j + k)
270+
filled[i+k] |= 1 << (j + w - 1)
271+
}
272+
dfs(i, j+w, t+1)
273+
}
274+
for x := i; x < i+mx; x++ {
275+
for y := j; y < j+mx; y++ {
276+
filled[x] ^= 1 << y
277+
}
278+
}
279+
}
280+
}
281+
dfs(0, 0, 0)
282+
return ans
283+
}
284+
285+
func min(a, b int) int {
286+
if a < b {
287+
return a
288+
}
289+
return b
290+
}
74291
```
75292

76293
### **...**

0 commit comments

Comments
 (0)