BF
所有把手只会改变一次此状态,如改变两次则等价与不改变,对于每一个把手只有操作与不操作两种选择,共有2 ^ 16种不同的操作,通过一个16位的二进制数表示各个把手是否进行操作,将所有组合从小到大枚举,即从0到2 ^ 16 - 1 得到的就是最小字典序,对于每一次操作,使用一个8位二进制数记录影响的位置,每一次操作将当前状态state的对应位置与分别与1异或,即可实现取反操作,使用一个change数组,将该位置操作后会影响的位置记录为1,而后直接异或即可
#include <iostream>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
int change[4][4];
int get(int x, int y)
{
return x * 4 + y;
}
int main()
{
int state = 0;
for(int i = 0; i < 4; i++)
{
string s;
cin >> s;
for(int j = 0; j < 4; j++)
{
if(s[j] == '+') // + -> 1 闭合
state += 1 << get(i, j);
}
}
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
for(int k = 0; k < 4; k++)
{
change[i][j] += 1 << get(i, k);
change[i][j] += 1 << get(k, j);
}
change[i][j] -= 1 << get(i, j);
// cout << change[i][j] << endl;
}
}
vector<PII>res; //2 ^ 16 种不同的操作
//自小到大枚举,自动为字典序
for(int i = 0; i < 1 << 16; i++)
{
int now = state;
vector<PII>path;
for(int j = 0; j < 16; j++)
{
if(i >> j & 1)
{
now ^= change[j / 4][j % 4];
path.push_back({j / 4, j % 4});
}
}
if(!now && (res.empty() || res.size() > path.size())) res = path;
}
cout << res.size() << endl;
for(auto &i : res) cout << i.first + 1 << ' ' << i.second + 1 << endl;
return 0;
}