Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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‎

Lines changed: 234 additions & 1 deletion
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)

AltStyle によって変換されたページ (->オリジナル) /