飞行员兄弟

 

 

 之前做过这道题目,详解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 }

 

posted @ 2020-11-17 10:40  kyk333  阅读(134)  评论(0编辑  收藏  举报