fork download
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. const int INF = 1e9;
  7. int n;
  8. int a[22][22]; // 初始矩阵
  9.  
  10. int main() {
  11. cin >> n;
  12. for (int i = 1; i <= n; i++) {
  13. string s;
  14. cin >> s;
  15. for (int j = 1; j <= n; j++) {
  16. a[i][j] = s[j-1] - '0';
  17. }
  18. }
  19. int ans = INF;
  20. int total_masks = 1 << n;
  21. // 用于存储行的数组,多出两个边界元素(索引0和n+1)方便处理
  22. int prev_row[22], curr_row[22], next_row[22];
  23. for (int mask = 0; mask < total_masks; mask++) {
  24. // 初始化prev_row全0
  25. memset(prev_row, 0, sizeof(prev_row));
  26. // 设置curr_row为mask对应的第一行操作
  27. memset(curr_row, 0, sizeof(curr_row));
  28. for (int j = 1; j <= n; j++) {
  29. curr_row[j] = (mask >> (j-1)) & 1;
  30. }
  31. int total_ops = __builtin_popcount(mask); // 第一行的操作次数
  32. // 逐行确定剩余行的操作
  33. for (int i = 1; i < n; i++) {
  34. // 计算下一行操作
  35. memset(next_row, 0, sizeof(next_row));
  36. for (int j = 1; j <= n; j++) {
  37. next_row[j] = a[i][j] ^ curr_row[j] ^ prev_row[j] ^ curr_row[j-1] ^ curr_row[j+1];
  38. }
  39. // 累加下一行的操作次数
  40. for (int j = 1; j <= n; j++) {
  41. total_ops += next_row[j];
  42. }
  43. // 更新行:当前行变为上一行,下一行变为当前行
  44. memcpy(prev_row, curr_row, sizeof(curr_row));
  45. memcpy(curr_row, next_row, sizeof(next_row));
  46. }
  47. // 验证最后一行是否满足全0条件
  48. bool ok = true;
  49. for (int j = 1; j <= n; j++) {
  50. int val = curr_row[j] ^ prev_row[j] ^ curr_row[j-1] ^ curr_row[j+1];
  51. if (val != a[n][j]) {
  52. ok = false;
  53. break;
  54. }
  55. }
  56. if (ok) {
  57. ans = min(ans, total_ops);
  58. }
  59. }
  60. if (ans == INF) {
  61. cout << -1 << endl;
  62. } else {
  63. cout << ans << endl;
  64. }
  65. return 0;
  66. }
Success #stdin #stdout 0s 5280KB
stdin
3
1 1 1
1 1 1
1 1 1
stdout
-1