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

    地址  https://www.acwing.com/problem/content/118/

    “飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。

    已知每个把手可以处于以下两种状态之一:打开或关闭。

    只有当所有把手都打开时,冰箱才会打开。

    把手可以表示为一个4х4的矩阵,您可以改变任何一个位置[i,j]上把手的状态。

    但是,这也会使得第i行和第j列上的所有把手的状态也随着改变。

    请你求出打开冰箱所需的切换把手的次数最小值是多少。

    输入格式

    输入一共包含四行,每行包含四个把手的初始状态。

    符号“+”表示把手处于闭合状态,而符号“-”表示把手处于打开状态。

    至少一个手柄的初始状态是关闭的。

    输出格式

    第一行输出一个整数N,表示所需的最小切换把手次数。

    接下来N行描述切换顺序,每行输入两个整数,代表被切换状态的把手的行号和列号,数字之间用空格隔开。

    数据范围

    1i,j4

    输入样例:
    -+--
    ----
    ----
    -+--
    输出样例:
    6
    1 1
    1 3
    1 4
    4 1
    4 3
    4 4
    注意:如果存在多种打开冰箱的方式,则按照优先级整体从上到下,同行从左到右打开。
    

      

    题解 没有剪枝等捷径 就是考核位运算

    使用int change[4][4] 记录任意一个按钮点击后的变化

    0~1<<16 二进制代表各种按钮的按法组合 然后遍历尝试

    代码如下

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 
     5 
     6 using namespace std;
     7 
     8 typedef pair<int,int> PII;
     9 
    10 
    11 int change[4][4]={0};
    12 
    13 int get(int x,int y){
    14     return x*4+y;
    15 }
    16 
    17 
    18 
    19 int main()
    20 {
    21     int state = 0; 
    22     for(int i = 0;i < 4;i++){
    23         string tmpStr;
    24         cin >> tmpStr;
    25         for(int j = 0; j < tmpStr.size();j++){
    26             if(tmpStr[j] == '+'){
    27                 state += 1<<get(i,j);
    28             }
    29         }
    30     }
    31     
    32     //制作每次点击某个开关后的变化表格
    33     for(int i =0;i < 4;i++){
    34         for(int j = 0; j < 4;j++){
    35             for(int k = 0; k < 4;k++){
    36                 change[i][j] += 1<< get(i,k);
    37                 change[i][j] += 1 <<get(k,j);
    38             }
    39             //选择的点回增加两次,减少1
    40             change[i][j] -= 1 << get(i,j);
    41         }
    42     }
    43     
    44     vector<PII> res;
    45     //遍历各种可能的点击开关的方案 16个按钮选出任意N个点击  从0-16个的排列组合就是0~ 1<<16;
    46     for(int k = 0;k < 1 << 16;k++){
    47         int now = state; 
    48         vector<PII> path;
    49         //当前选择的点击方案 点击了那些按钮
    50         for(int i = 0; i< 16;i++){
    51             if(k >> i & 1){
    52                 //该按钮按下了
    53                  int x = i/4,y = i%4;
    54                 now ^= change[x][y];
    55                 path.push_back({x,y});
    56             }
    57             if(!now && ( res.empty() ||  res.size() > path.size() ))
    58                 res = path;
    59         }
    60     }
    61     
    62      cout << res.size() << endl;
    63     for(auto p : res)
    64         cout << p.first +1 << ' ' << p.second+1 << endl;
    65 
    66     
    67     return 0;
    68 }
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    《算法导论》读书笔记--第三章函数的增长 课后题
    《利用python进行数据分析》读书笔记--第五章 pandas入门
    《利用python进行数据分析》读书笔记--第四章 numpy基础:数组和矢量计算
    《利用python进行数据分析》读书笔记--第三章 ipython使用
    《算法导论》读书笔记--第三章 函数的增长
    《利用python进行数据分析》读书笔记 --第一、二章 准备与例子
    《R语言实战》读书笔记--学习张丹日志
    《R语言实战》读书笔记 第七章--基本统计分析
    解决Mybatis-plus高版本不向后兼容的问题
    【Javascript】: for循环中定义的变量在for循环体外也有效
  • 原文地址:https://www.cnblogs.com/itdef/p/11104876.html
Copyright © 2011-2022 走看看