思路:纵观全局,把手的数量固定为16,因此利用暴力解决即可,二进制思想0代表不操作把手1代表操作把手,枚举所有状态即可,此外我们将二维数组可以映射成具体数字(映射数字/4代表横轴,映射数字%4代表列轴),具体可以参照代码注释
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char st[20][20];//存储把手初始态
char lit[20][20];//把手备份
int ans;
void turn(int t)//改变把手的行和列
{
int dx=t/4;
int dy=t%4;
for(int i=0;i<=3;i++)
{
if(lit[i][dy]=='+')
{
lit[i][dy]='-';
}
else
{
lit[i][dy]='+';
}
}
for(int i=0;i<=3;i++)
{
if(lit[dx][i]=='+')
{
lit[dx][i]='-';
}
else
{
lit[dx][i]='+';
}
}
if(lit[dx][dy]=='+')
{
lit[dx][dy]='-';
}
else
{
lit[dx][dy]='+';
}
ans++;
}
bool check()//检查把手是否全为打开状态
{
for(int i=0;i<=3;i++)
{
for(int j=0;j<=3;j++)
{
if(lit[i][j]=='+')
{
return false;
}
}
}
return true;
}
int main()
{
int fills;
for(int i=0;i<4;i++)
{
cin>>st[i];
}
int mins=100;
for(int i=0;i< 1<<16;i++)//从0到2的16次方枚举
{
ans=0;
memcpy(lit,st,sizeof st);
for(int j=0;j<16;j++)
{
if(i>>j&1)//如果第j个把手为1则反转
{
turn(j);
}
}
if(check()){
mins=min(mins,ans);
fills=i;
}
}
cout<<mins<<endl;
for(int i=0;i<=15;i++)
{
if(fills>>i&1)
{
cout<<i/4+1<<" "<<i%4+1<<endl;
}
}
return 0;
}