Giả sử chúng ta có một bảng N x N chỉ chứa các số 0 và 1. Bây giờ trong mỗi lần di chuyển, chúng ta có thể hoán đổi 2 hàng hoặc 2 cột bất kỳ. Chúng ta phải tìm số nước đi tối thiểu để biến bàn cờ thành "bàn cờ". Nếu giải pháp không tồn tại, thì trả về -1.
Vì vậy, nếu đầu vào giống như -
| | | |
| | | |
| | | |
| | | |
Sau đó, đầu ra sẽ là 2, vì hai cột đầu tiên trong lần di chuyển đầu tiên, sau đó bảng sẽ giống như -
| | | |
| | | |
| | | |
| | | |
Sau đó, hoán đổi hàng thứ hai và thứ 3 -
| | | |
| | | |
| | | |
| | | |
Đây là bàn cờ
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
- n:=kích thước của b
- để khởi tạo i:=0, khi i
- để khởi tạo j:=0, khi j
- nếu b [0, 0] XOR b [0, j] XOR b [i, 0] XOR b [i, j] khác 0, thì -
- trả về -1
- để khởi tạo j:=0, khi j
- trả về -1
- trả về -1
- nếu colSwap mod 2 khác 0, thì -
- colSwap:=n - colSwap
- nếu rowSwap mod 2 khác 0, thì -
- rowSwap:=n - rowSwap
- colSwap:=tối thiểu colSwap và n - colSwap
- rowSwap:=tối thiểu rowSwap và n - rowSwap
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
Ví dụ
#include <bits/stdc++.h> using namespace std; class Solution { public: int movesToChessboard(vector<vector<int>>& b) { int n = b.size(); for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(b[0][0] ^ b[0][j] ^ b[i][0] ^ b[i][j]) return -1; } } int rowSum = 0; int colSum = 0; int rowSwap = 0; int colSwap = 0; for(int i = 0; i < n; i++){ rowSum += b[i][0]; colSum += b[0][i]; rowSwap += b[i][0] == i % 2; colSwap += b[0][i] == i % 2; } if(rowSum != n/2 && rowSum != (n + 1)/2)return -1; if(colSum != n/2 && colSum != (n + 1)/2)return -1; if(n % 2 == 1){ if(colSwap % 2) colSwap = n - colSwap; if(rowSwap % 2) rowSwap = n - rowSwap; }else{ colSwap = min(colSwap, n - colSwap); rowSwap = min(rowSwap, n - rowSwap); } return (rowSwap + colSwap)/2; } }; main(){ Solution ob; vector<vector<int>> v = {{0,1,1,0},{0,1,1,0},{1,0,0,1},{1,0,0,1}}; cout << (ob.movesToChessboard(v)); }
Đầu vào
{{0,1,1,0},{0,1,1,0},{1,0,0,1},{1,0,0,1}};
Đầu ra
2