飞行员兄弟

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

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

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

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

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

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

输入格式

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

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

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

输出格式

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

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

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

数据范围

1≤i,j≤41≤i,j≤4

输入样例:

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

输出样例:

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

1、核心思路:

(1)暴力枚举1>>16种方案,即不管传入的是撒样子,这些按的方案总共就2的16次方种,

(2)上面已经确定了形态,然后判断,哪种方案能使全开,之后返回最小步数,

(3),接下来,用vector容器,存步数,

2、与费解的开关不同的是,

(1)要记录,按的位置,

就要用vector容器来存,(此处用数组存就会被覆盖),

模版是pair<int ,int >模版,就是定义一个容器的模版是两个int 类型的结构体类型,

比较的是容器的容量.size( )函数,

c++范围搜索,

3、要学的知识,

(1)vector容器定义,用哪样的模版定义,typedef pair<int,int> PII;

vector <PII> res;

c++中pair的用法

(2)vector容器函数,的应用,

C++ 中vector的使用方法_c++vector

(3)基于范围for循环

基于范围for循环

其中auto,auto在C++99中不支持,考试的时候如果编译不过,换成对应的变量类型即可。就是PII结构体类型

下面是代码啦, 

希望遗忘不会赶上来,,,

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>


using namespace std;

typedef pair<int ,int> PII;//定义pair模版(类似于存两个类似
                           //于只有两个成员变量的结构体变量。一个pair包含两个成员变量first变量和second变量,
                           //基本操作都和结构体类似。)
char g[10][10];

void turn(int x, int y)
{
    for(int i =0 ;i< 4 ;i++)
    {
        if(g[i][y]=='-') g[i][y] = '+';
        else g[i][y] = '-';
        
        if(g[x][i]=='-') g[x][i] = '+';
        else g[x][i]= '-';
    }
    if(g[x][y]=='-') g[x][y] = '+';
        else g[x][y]= '-';
}

int get( int i,int j) //得到编号,0123456789...15用于让位操作按哪个,
{
    return i*4 + j%4;
}

void work()
{
    vector<PII> res;//声明res为pair模版的容器,
    //枚举每种按的方案
    for(int k=0 ;k<1<<16 ; k++ )
    {
        vector<PII> temp;//用temp来记录,每种方案的步数,步骤
        int ret =0 ;
        char backup[10][10];
        memcpy(backup,g,sizeof g);
        
        在每种情况下操作数组(按)
        for(int i=0 ;i<4;i++)
            for(int j=0 ; j<4 ; j++)
            {
                if( k>> get(i,j) & 1)
                {
                    temp.push_back({i,j}); //push_back()函数 在Vector最后添加一个元素
                    turn(i,j);
                }
            }
        //判断整个数组
        bool is_successful = true;
        for(int i=0 ;i<4;i++)
        {
            for(int j=0 ;j<4; j++)
            {
                if(g[i][j]=='+')
                    is_successful = false;
            }
        }
         //找最小的步数
        if(is_successful) //找到最小步数,符给res带出去
        {
                                                //.size()、.empty()函数,都是容器函数
                                                 //empty() 判断vector是否为空,如果返回true为空
            if(res.empty() || res.size() > temp.size()) res = temp;  
                                                //先判空,是因为,res容器初始是空
                                                //小于号,将最小的.size(),即容器中,存的步数
        }
        
        memcpy(g,backup,sizeof g);
        
    }
    cout<<res.size()<<endl;
    for(PII k:res) cout<< k.first+1 <<" "<< k.second+1 <<endl; //C++基于范围的for循环,PII变量类型
}


int main()
{
    for(int i=0 ;i<4; i++) cin>>g[i];
    work();
}

                          冬日西沉的残阳余晖在原西河对面的山尖上留了不多的一点。

                                                                                ——《平凡的世界》

                                                                                2022年2月10日15:17:40

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值