Skip to content

Commit 4014528

Browse files
committed
feat: add solutions to lc problem: No.0782
No.0782.Transform to Chessboard
1 parent 3d9a1df commit 4014528

File tree

6 files changed

+654
-1
lines changed

6 files changed

+654
-1
lines changed

solution/0700-0799/0782.Transform to Chessboard/README.md

+234-1
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,255 @@
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64+
**方法一:规律观察 + 状态压缩**
65+
66+
在一个有效的棋盘中,有且仅有两种“行”。
67+
68+
例如,如果棋盘中有一行为“01010011”,那么任何其它行只能为“01010011”或者“10101100”。列也满足这种性质。
69+
70+
另外,每一行和每一列都有一半 $0$ 和一半 $1$。假设棋盘为 $n \times n$:
71+
72+
- 若 $n = 2 \times k$,则每一行和每一列都有 $k$ 个 $1$ 和 $k$ 个 $0$。
73+
- 若 $n = 2 \times k + 1$,则每一行都有 $k$ 个 $1$ 和 $k + 1$ 个 $0$,或者 $k + 1$ 个 $1$ 和 $k$ 个 $0$。
74+
75+
基于以上的结论,我们可以判断一个棋盘是否有效。若有效,可以计算出最小的移动次数。
76+
77+
若 $n$ 为偶数,最终的合法棋盘有两种可能,即第一行的元素为“010101...”,或者“101010...”。我们计算出这两种可能所需要交换的次数的较小值作为答案。
78+
79+
若 $n$ 为奇数,那么最终的合法棋盘只有一种可能。如果第一行中 $0$ 的数目大于 $1$,那么最终一盘的第一行只能是“01010...”,否则就是“10101...”。同样算出次数作为答案。
80+
81+
时间复杂度 $O(n^2)$。
82+
6483
<!-- tabs:start -->
6584

6685
### **Python3**
6786

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

7089
```python
71-
90+
class Solution:
91+
def movesToChessboard(self, board: List[List[int]]) -> int:
92+
def f(mask, cnt):
93+
ones = mask.bit_count()
94+
if n & 1:
95+
if abs(n - 2 * ones) != 1 or abs(n - 2 * cnt) != 1:
96+
return -1
97+
if ones == n // 2:
98+
return n // 2 - (mask & 0xAAAAAAAA).bit_count()
99+
return (n + 1) // 2 - (mask & 0x55555555).bit_count()
100+
else:
101+
if ones != n // 2 or cnt != n // 2:
102+
return -1
103+
cnt0 = n // 2 - (mask & 0xAAAAAAAA).bit_count()
104+
cnt1 = n // 2 - (mask & 0x55555555).bit_count()
105+
return min(cnt0, cnt1)
106+
107+
n = len(board)
108+
mask = (1 << n) - 1
109+
rowMask = colMask = 0
110+
for i in range(n):
111+
rowMask |= board[0][i] << i
112+
colMask |= board[i][0] << i
113+
revRowMask = mask ^ rowMask
114+
revColMask = mask ^ colMask
115+
sameRow = sameCol = 0
116+
for i in range(n):
117+
curRowMask = curColMask = 0
118+
for j in range(n):
119+
curRowMask |= board[i][j] << j
120+
curColMask |= board[j][i] << j
121+
if curRowMask not in (rowMask, revRowMask) or curColMask not in (colMask, revColMask):
122+
return -1
123+
sameRow += curRowMask == rowMask
124+
sameCol += curColMask == colMask
125+
t1 = f(rowMask, sameRow)
126+
t2 = f(colMask, sameCol)
127+
return -1 if t1 == -1 or t2 == -1 else t1 + t2
72128
```
73129

74130
### **Java**
75131

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

78134
```java
135+
class Solution {
136+
private int n;
137+
138+
public int movesToChessboard(int[][] board) {
139+
n = board.length;
140+
int mask = (1 << n) - 1;
141+
int rowMask = 0, colMask = 0;
142+
for (int i = 0; i < n; ++i) {
143+
rowMask |= board[0][i] << i;
144+
colMask |= board[i][0] << i;
145+
}
146+
int revRowMask = mask ^ rowMask;
147+
int revColMask = mask ^ colMask;
148+
int sameRow = 0, sameCol = 0;
149+
for (int i = 0; i < n; ++i) {
150+
int curRowMask = 0, curColMask = 0;
151+
for (int j = 0; j < n; ++j) {
152+
curRowMask |= board[i][j] << j;
153+
curColMask |= board[j][i] << j;
154+
}
155+
if (curRowMask != rowMask && curRowMask != revRowMask) {
156+
return -1;
157+
}
158+
if (curColMask != colMask && curColMask != revColMask) {
159+
return -1;
160+
}
161+
sameRow += curRowMask == rowMask ? 1 : 0;
162+
sameCol += curColMask == colMask ? 1 : 0;
163+
}
164+
int t1 = f(rowMask, sameRow);
165+
int t2 = f(colMask, sameCol);
166+
return t1 == -1 || t2 == -1 ? -1 : t1 + t2;
167+
}
168+
169+
private int f(int mask, int cnt) {
170+
int ones = Integer.bitCount(mask);
171+
if (n % 2 == 1) {
172+
if (Math.abs(n - ones * 2) != 1 || Math.abs(n - cnt * 2) != 1) {
173+
return -1;
174+
}
175+
if (ones == n / 2) {
176+
return n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
177+
}
178+
return (n / 2 + 1) - Integer.bitCount(mask & 0x55555555);
179+
} else {
180+
if (ones != n / 2 || cnt != n / 2) {
181+
return -1;
182+
}
183+
int cnt0 = n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
184+
int cnt1 = n / 2 - Integer.bitCount(mask & 0x55555555);
185+
return Math.min(cnt0, cnt1);
186+
}
187+
}
188+
}
189+
```
190+
191+
### **C++**
192+
193+
```cpp
194+
class Solution {
195+
public:
196+
int n;
197+
int movesToChessboard(vector<vector<int>>& board) {
198+
n = board.size();
199+
int mask = (1 << n) - 1;
200+
int rowMask = 0, colMask = 0;
201+
for (int i = 0; i < n; ++i) {
202+
rowMask |= board[0][i] << i;
203+
colMask |= board[i][0] << i;
204+
}
205+
int revRowMask = mask ^ rowMask;
206+
int revColMask = mask ^ colMask;
207+
int sameRow = 0, sameCol = 0;
208+
for (int i = 0; i < n; ++i) {
209+
int curRowMask = 0, curColMask = 0;
210+
for (int j = 0; j < n; ++j) {
211+
curRowMask |= board[i][j] << j;
212+
curColMask |= board[j][i] << j;
213+
}
214+
if (curRowMask != rowMask && curRowMask != revRowMask) return -1;
215+
if (curColMask != colMask && curColMask != revColMask) return -1;
216+
sameRow += curRowMask == rowMask;
217+
sameCol += curColMask == colMask;
218+
}
219+
int t1 = f(rowMask, sameRow);
220+
int t2 = f(colMask, sameCol);
221+
return t1 == -1 || t2 == -1 ? -1 : t1 + t2;
222+
}
223+
224+
int f(int mask, int cnt) {
225+
int ones = __builtin_popcount(mask);
226+
if (n & 1) {
227+
if (abs(n - ones * 2) != 1 || abs(n - cnt * 2) != 1) return -1;
228+
if (ones == n / 2) return n / 2 - __builtin_popcount(mask & 0xAAAAAAAA);
229+
return (n + 1) / 2 - __builtin_popcount(mask & 0x55555555);
230+
} else {
231+
if (ones != n / 2 || cnt != n / 2) return -1;
232+
int cnt0 = (n / 2 - __builtin_popcount(mask & 0xAAAAAAAA));
233+
int cnt1 = (n / 2 - __builtin_popcount(mask & 0x55555555));
234+
return min(cnt0, cnt1);
235+
}
236+
}
237+
};
238+
```
79239

240+
### **Go**
241+
242+
```go
243+
func movesToChessboard(board [][]int) int {
244+
n := len(board)
245+
mask := (1 << n) - 1
246+
rowMask, colMask := 0, 0
247+
for i := 0; i < n; i++ {
248+
rowMask |= board[0][i] << i
249+
colMask |= board[i][0] << i
250+
}
251+
revRowMask := mask ^ rowMask
252+
revColMask := mask ^ colMask
253+
sameRow, sameCol := 0, 0
254+
for i := 0; i < n; i++ {
255+
curRowMask, curColMask := 0, 0
256+
for j := 0; j < n; j++ {
257+
curRowMask |= board[i][j] << j
258+
curColMask |= board[j][i] << j
259+
}
260+
if curRowMask != rowMask && curRowMask != revRowMask {
261+
return -1
262+
}
263+
if curColMask != colMask && curColMask != revColMask {
264+
return -1
265+
}
266+
if curRowMask == rowMask {
267+
sameRow++
268+
}
269+
if curColMask == colMask {
270+
sameCol++
271+
}
272+
}
273+
f := func(mask, cnt int) int {
274+
ones := bits.OnesCount(uint(mask))
275+
if n%2 == 1 {
276+
if abs(n-ones*2) != 1 || abs(n-cnt*2) != 1 {
277+
return -1
278+
}
279+
if ones == n/2 {
280+
return n/2 - bits.OnesCount(uint(mask&0xAAAAAAAA))
281+
}
282+
return (n+1)/2 - bits.OnesCount(uint(mask&0x55555555))
283+
} else {
284+
if ones != n/2 || cnt != n/2 {
285+
return -1
286+
}
287+
cnt0 := n/2 - bits.OnesCount(uint(mask&0xAAAAAAAA))
288+
cnt1 := n/2 - bits.OnesCount(uint(mask&0x55555555))
289+
return min(cnt0, cnt1)
290+
}
291+
}
292+
t1 := f(rowMask, sameRow)
293+
t2 := f(colMask, sameCol)
294+
if t1 == -1 || t2 == -1 {
295+
return -1
296+
}
297+
return t1 + t2
298+
}
299+
300+
func abs(x int) int {
301+
if x < 0 {
302+
return -x
303+
}
304+
return x
305+
}
306+
307+
func min(a, b int) int {
308+
if a < b {
309+
return a
310+
}
311+
return b
312+
}
80313
```
81314

82315
### **...**

0 commit comments

Comments
 (0)