116. 飞行员兄弟
Posted 幽殇默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了116. 飞行员兄弟相关的知识,希望对你有一定的参考价值。
116. 飞行员兄弟
题目的意思就是:
你动一个它是一个大的十字的变化。
解题思路:
- 枚举出所有的情况,即216种情况。我们用0代表不操作,1代表操作。
啥意思呢?
例 : 0000 0000 0000 0001 就代表的是只操作第一个开关
例 : 0000 0000 0001 0001 就代表的是操作第一个开关和第五个开关 - 对每一种情况我们遍历每一次的操作,最后看灯是不是全亮。
- 注意操作的时候我们要把二维的数组下标变成一维的数组。这样才可以看各个位是不是1,决定要不要操作。
注意的点是:
- 注意操作的时候我们要把二维的数组下标变成一维的数组。这样才可以看各个位是不是1,决定要不要操作。
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N=5;
char g[N][N],backup[N][N];
int get(int x,int y)//将其二维的下标,转化为一维的下标
{
return x*4+y;
}
void turn_one(int x,int y)
{
if(g[x][y]=='+') g[x][y]='-';
else g[x][y]='+';
}
void turn_all(int x,int y)
{
for(int i=0;i<4;i++)
{
turn_one(x,i);
turn_one(i,y);
}
turn_one(x,y);//你按的这个按钮变了两次,需要单独的再按一次。
}
int main()
{
for(int i=0;i<=4;i++) //读取信息
cin>>g[i];
vector<PII> res;//记录最优的解
for(int op=0;op<1<<16;op++)//枚举所有的可能 0代表不操作 1代表操作
{
vector<PII> temp;
memcpy(backup,g,sizeof g);//备份信息
//进行操作
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(op>>get(i,j)&1)//判断当前位是不是1(即要不要操作)
{
temp.push_back({i,j});//把该操作记录下来
turn_all(i,j);//执行按的操作
}
}
}
//判断灯泡是否全亮
bool has_closed=false;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(g[i][j]=='+')
has_closed=true;
}
}
if(has_closed==false)
{
if(res.empty()||res.size()>temp.size())
res=temp;
}
memcpy(g,backup,sizeof g);//还原现场,为下一次的遍历做准备
}
cout<<res.size()<<endl;
for(auto op : res)
cout<<op.x+1<<" "<<op.y+1<<endl;
}
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int a[10][10],b[10][10];
void turn(int x,int y)
{
for(int i=0;i<4;i++) b[x][i]^=1,b[i][y]^=1;
b[x][y]^=1;//按了两次得再按一次
}
int main(void)
{
string s[10];
for(int i=0;i<4;i++) cin>>s[i];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(s[i][j]=='+') a[i][j]=0;
else a[i][j]=1;
vector<PII> ans;
for(int i=0;i<(1<<16);i++)
{
vector<PII>temp;
memcpy(b,a,sizeof a);
for(int j=0;j<16;j++)
{
if( (i>>j) & 1 )
{
turn(j/4,j%4);
temp.push_back({j/4,j%4});
}
}
bool flag=true;
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
if(!b[j][k]) flag=false;
if(flag && ( ans.size()>temp.size() || ans.empty() ) ) ans=temp;
}
cout<<ans.size()<<endl;
for(auto op: ans) cout<<op.first+1<<" "<<op.second+1<<endl;
return 0;
}
以上是关于116. 飞行员兄弟的主要内容,如果未能解决你的问题,请参考以下文章