zoukankan      html  css  js  c++  java
  • 飞行员兄弟(暴力枚举)

    飞行员兄弟(暴力枚举)

    题目描述:“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。已知每个把手可以处于以下两种状态之一:打开或关闭。

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

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

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

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

    输入格式

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

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

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

    输出格式

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

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

    注意:如果存在多种打开冰箱的方式,则按照优先级整体从上到下,同行从左到右打开。

    数据范围

    1≤i,j≤4

    输入样例:

     -+--
     ----
     ----
     -+--

    输出样例:

     6
     1 1
     1 3
     1 4
     4 1
     4 3
     4 4

     

     #include<algorithm>
     #include<iostream>
     #include<cstring>
     #include<cstdio>
     using namespace std;
     
     char g[6][6];//把手矩阵,将来我们都是对这个数组做处理
     char backup1[6][6];//备份作用,每循环一次,就将backup1中的数据拷回g中。
     int way[6][6];//way数组保存的是哪个把手要进行状态转换,如:way[1][1]=1,就表示2 2这个把手需要被转换
     int backup2[6][6];//backup2用来保存最终结果。只要发现step比res小,就将way中的数据拷入到backup2中,更新最优解。
     
     void turn(int x,int y){
     
         for(int i=0;i<4;i++){
             if(g[x][i]=='-'){
                 g[x][i]='+';
            }else{
                 g[x][i]='-';
            }
        }
         for(int j=0;j<4;j++){
             if(g[j][y]=='-'){
                 g[j][y]='+';
            }else{
                 g[j][y]='-';
            }
        }
     
         //turn方法比较简单,但是x,y这个点需要注意,该点要被转换三次(两次for回到最初,所以还需额外一次),
         //所以下面这几行代码不能少。我就是在这栽了15分钟。。。。。。
         if(g[x][y]=='-'){
             g[x][y]='+';
        }else{
             g[x][y]='-';
        }
     }
     
     int main(){
         for(int i=0;i<4;i++) cin>>g[i];//读入把手矩阵
         long long res = 9999999999;//起初把res设的尽可能大
         for(long long i=0;i<1<<16;i++){//因为i范围很小,所以我们就算一一枚举1<<16的把手状态也不会超时
             int step=0;
             memcpy(backup1,g,sizeof g);
     
             memset(way,0,sizeof way);//每次循环都要将way数组置零
     
     
             for(int j=0;j<16;j++){
                 if(i>>j&1){//表示低位把手要转换状态
                     step++;
                     turn(j/4,j%4);
                     way[j/4][j%4]=1;
                }
            }
             //内层循环完成后,判断把手是否全部开启
             bool success = true;
             for(int i=0;i<16;i++){
                 if(g[i/4][i%4]=='+'){
                     success = false;
                     break;
                }
            }
     
             if(success) {
                 if(res>step){
                     memcpy(backup2,way,sizeof way);
                     res = step;
                }
            }
     
     
             memcpy(g,backup1,sizeof g);//循环结束,把备份把手矩阵拷回g。
        }
     
         cout<<res<<endl;
         //bool win = true;
         for(int i=0;i<16;i++){
             if(backup2[i/4][i%4]){
                 cout<<(i/4)+1<<" "<<(i%4)+1<<endl;
            }
        }
     
         return 0;
     }
     
     作者:rookie_14
     链接:https://www.acwing.com/activity/content/code/content/931103/
     来源:AcWing
     著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

     

  • 相关阅读:
    Creating a generic Web Parts for hosting ASP.NET User Controls
    Speed Up SQL Server Apps 提高SQL Server应用程序的运行效率 (Part 1)
    How to use CreateChildContorls method inherited from System.Web.UI.Control
    How to quickly access Web Part Management Page
    SQL Script tips for MS SQL Server
    How to enable single signon service on the SPS
    A brief summary of UML & Rational Rose – Use Case Diagram, Part II
    Borland Together for Visual Studio.Net V2.0 安装问题
    Speed Up SQL Server Apps 提高SQL Server应用程序的运行效率 (Part 2)
    体验ReSharper V1.0 for VS.Net 2003 Part I
  • 原文地址:https://www.cnblogs.com/yuanshixiao/p/14469649.html
Copyright © 2011-2022 走看看