之前做过这道题目,详解https://www.cnblogs.com/fx1998/p/12785188.html
方法一:暴力枚举
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 5; 4 char g[N][N], bk[N][N]; 5 typedef pair<int, int> PII; 6 #define fi first 7 #define se second 8 int get(int x, int y) { 9 return x * 4 + y; 10 } 11 void turn_one(int x, int y) { 12 if (g[x][y] == '+') { 13 g[x][y] = '-'; 14 } else { 15 g[x][y] = '+'; 16 } 17 } 18 void turn_all(int x, int y) { 19 for (int i = 0; i < 4; i++) { 20 turn_one(x, i); 21 turn_one(i, y); 22 } 23 turn_one(x, y); 24 } 25 int main() { 26 for (int i = 0; i < 4; i++) { 27 cin >> g[i]; 28 } 29 vector<PII> res; 30 for (int op = 0; op < (1 << 16); op++) { 31 vector<PII> t; 32 memcpy(bk, g, sizeof g); //备份 33 for (int i = 0; i < 4; i++) { //操作 34 for (int j = 0; j < 4; j++) { 35 if (op >> get(i, j) & 1) { 36 t.push_back(make_pair(i, j)); 37 //t.push_back({i, j}); 38 turn_all(i, j); 39 } 40 } 41 } 42 //判断灯泡是否全亮 43 bool flag = true; 44 for (int i = 0; i < 4; i++) { 45 for (int j = 0; j < 4; j++) { 46 if (g[i][j] == '+') { 47 flag = false; 48 } 49 } 50 } 51 if (flag) { 52 if (res.empty() || res.size() > t.size()) { 53 res = t; 54 } 55 } 56 memcpy(g, bk, sizeof g); //还原 57 } 58 cout << res.size() << endl; 59 for (int i = 0; i < res.size(); i++) { 60 cout << res[i].fi + 1 << " " << res[i].se + 1 << endl; 61 } 62 return 0; 63 }
方法二:二进制优化
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int,int> PII; 4 const int N = 4, INF = 100; 5 int change[N][N]; //change存储操作每个开关时需要异或的数 6 int get(int x, int y) { //求出x行y列的编号 7 return 4 * x + y; 8 } 9 int main() { 10 for (int i = 0; i < 4; i++) { 11 for (int j = 0; j < 4; j++) { 12 //当前枚举到(i,j)这个开关 13 for (int k = 0; k < 4; k++) { 14 change[i][j] += (1 << get(i, k)) + (1 << get(k, j)); 15 } 16 change[i][j] -= 1 << get(i, j); 17 } 18 } 19 int state = 0; //用一个整数表示整个棋盘的状态 20 for (int i = 0; i < 4; i++) { 21 string line; 22 cin >> line; 23 for (int j = 0; j < 4; j++) { 24 if (line[j] == '+') { 25 state += (1 << get(i, j)); 26 } 27 } 28 } 29 vector<PII> res; 30 //res是答案,temp是每种方案 31 for (int i = 0; i < (1 << 16); i ++ ) { 32 int now = state; 33 vector<PII> temp; 34 for (int j = 0; j < 16; j++) { 35 if (i >> j & 1) { 36 int x = j / 4, y = j % 4; 37 now ^= change[x][y]; 38 temp.push_back({x, y}); 39 } 40 } 41 if (!now && (res.empty() || res.size() > temp.size())) { 42 res = temp; 43 } 44 } 45 cout << res.size() << endl; 46 for (int i = 0; i < res.size(); i++) { 47 cout << res[i].first + 1 << " " << res[i].second + 1 << endl; 48 } 49 return 0; 50 }