• AcWing 飞行员兄弟 二进制枚举


    这道题目和费解的开关https://www.cnblogs.com/fx1998/p/12767815.html类似一点点。

    解题思路:

    一共有16个开关,每个开关可以选择按一下或不按这两种状态。

    所以可能的结果一共有2^16=65536,对于每种情况,再遍历一下4*4的矩阵看是否全是打开的,再乘以16,2^16 * 16 = 1,048,576‬。再加上其他运算所用的时间,总时间复杂度很小,可以直接暴力。

    但是费解的开关是5*5,所有可能的情况是2^25=33,554,432‬,时间复杂度较高,所以不考虑暴力。

    所以用一个16位的二进制数字,来表示进行的操作,0表示不按,1表示按。用二进制从0~2^16 - 1,枚举所有的情况。

    将4*4棋盘的开关标号为:

    0  1  2  3

    4  5  6  7

    8  9  10  11

    12  13  14  15

    这道题目还可以用二进制来优化,但没必要,暴力可过。

     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 }
  • 相关阅读:
    ansible笔记(11):初识ansible playbook(二)
    Linux下查看占用CPU与内存最高的进程
    ansible笔记(10):初识ansible playbook
    AbpZero Http 模式下 Chrome浏览器因Cookie 不能登录
    Tomcat 8443&8080 并存
    接入腾讯cos文件存储
    安卓包打渠道标签
    java Android与PHP encode的区别
    thinkphp常用
    phalcon task任务
  • 原文地址:https://www.cnblogs.com/fx1998/p/12785188.html
Copyright © 2020-2023  润新知