题目描述
给定4 * 4 的图 要求把图全部变成'-'号
按一下某一个点 会吧这行列的元素都翻转
问最少需要几步 并且输出操作步骤
样例
Sample Input
-+--
----
----
-+--
Sample Output
6
1 1
1 3
1 4
4 1
4 3
4 4
思路
- 用一个整数state(二进制)代表当前的状态, 数位上的,0代表-, 1代表+,4*4的图的所有的方案数为0到2^16-1, 我们字节枚举这些方案, 找出合法方案即可
- 对每个点的操作相当于把当前状态异或这个点的行列元素之和, 我们先把这个和存在数组a当中
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
int a[5][5];
vector<PII> ans;
vector<PII> path;
void init()
{
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
{
for(int k = 0; k < 4; k++)
{
a[i][j] += 1 << (i * 4 + k);
a[i][j] += 1 << (k * 4 + j);
}
a[i][j] -= 1 << (i * 4 + j);
}
}
int main()
{
int state = 0;
init();
for(int i = 0; i < 4; i++)
{
string s;
cin >> s;
for(int j = 0; j < s.size(); j++)
{
if(s[j] == '+')
state += 1 << (i * 4 + j);
}
}
for(int i = 0; i < 1 << 16; i++)
{
path.clear();
int t = state;
for(int j = 0; j <= 15; j++)
{
if((i >> j) & 1)
{
t ^= a[j / 4][j % 4];
PII tem;
tem.first = j / 4;
tem.second = j % 4;
path.push_back(tem);
}
}
if(t == 0)
{
if(ans.empty() || (ans.size() > path.size()))
ans = path;
}
}
cout << ans.size() << endl;
for(int i = 0; i < ans.size(); i++)
{
cout << ans[i].first + 1 << " " << ans[i].second + 1 << endl;
}
return 0;
}