“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有 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;
(2)vector容器函数,的应用,
(3)基于范围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