zoukankan      html  css  js  c++  java
  • 116. 飞行员兄弟

    开关问题满足的条件:

    1. 最优解情况下,一个开关只按一次
    2. 开关的顺序无关

    由于数据范围比较小,可以直接枚举出所有开关情况(0~2^16 - 1),然后操作一下灯泡,然后检查一下是不是全开开了即可,注意最后答案要求字典序最小的步数最少的解。

    之所以从0~2^16枚举是因为后面一个数中包含的1的个数一定>= 前面一个数的1的个数,所以从小到大找到的第一个解就是答案。

    暴力代码

    #include<iostream>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    #define PII pair<int, int>
    
    const int N = 10;
    
    char g[N][N], backup[N][N];
    
    void turn(int x, int y){
        g[x][y] ^= 6;
        for(int i = 0; i < 4; i ++){
            g[x][i] ^= 6;
            g[i][y] ^= 6;
        }
    }
    
    int check(){
        for(int i = 0; i < 4; i ++)
            for(int j = 0; j < 4; j ++)
                if(g[i][j] == '+') return 0;
                
        return 1;
    }
    
    int main(){
        for(int i = 0; i < 4; i ++) cin >> g[i];
        
        vector<PII> path;
    
        memcpy(backup, g, sizeof g);
        
        for(int i = (1 << 16) - 1; i >= 0; i --){
            for(int j = 0; j < 16; j ++){
                if((i >> j & 1) == 0){
                    turn(j / 4, j % 4);
                    path.push_back({j / 4, j % 4});
                }
            }
            
            if(check())
                break;
    
            memcpy(g, backup, sizeof g);
            path.clear();
        }
        
        cout << path.size() << endl;
        for(auto t : path) cout << t.first + 1 << ' ' << t.second + 1 << endl;
        
        return 0;
    }
    

    位运算

    优化成1维。

    #include<iostream>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    const int N = 10;
    
    #define PII pair<int, int>
    
    int g[N], backup[N];
    
    void turn(int x, int y){
        int d = 1 << (3 - y);
        g[x] ^= d;
        for(int i = 0; i < 4; i ++) g[i] ^= d;
        g[x] ^= (1 << 4) - 1;
    }
    
    int check(){
        for(int i = 0; i < 4; i ++)
            if(g[i]) return 0;
        
        return 1;
    }
    
    int main(){
        for(int i = 0; i < 4; i ++){
            for(int j = 0; j < 4; j ++){
                char c = getchar();
                g[i] = g[i] * 2 + (c == '+');
            }
            getchar();
        }
        
        vector<PII> path;
        
        memcpy(backup, g, sizeof g);
        
        for(int i = 0; i < 1 << 16; i ++){
            for(int j = 0; j < 16; j ++){
                if(i >> j & 1){
                    turn(j / 4, j % 4);
                    path.push_back({j / 4, j % 4});
                }
            }
            
            if(check()) break;
            path.clear();
            memcpy(g, backup, sizeof g);
        }
        
        cout << path.size() << endl;
        for(auto t : path) cout << t.first + 1 << ' ' << t.second + 1 << endl;
    }
    
  • 相关阅读:
    Android测试提升效率批处理脚本
    iOS系统设备网络抓包工具介绍:越狱和不越狱的办法
    用于管理Linux系统中的各种服务的命令service命令
    linux sort 命令详解
    在loadrunner操作中,所碰见问题及解决方法
    Unable to connect to the remote server 问题(已经解决)
    均值、中位数、众数
    修改Android 界面颜色
    设置Android程序图标和程序标题
    Android中的EditText默认时不弹出软键盘的方法
  • 原文地址:https://www.cnblogs.com/tomori/p/13452398.html
Copyright © 2011-2022 走看看