(暴力枚举) $O(n^2)$
看了y神视频,敲的和y神一样 加上自己的理解
C++ 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
int n, r;
int m1[4][4];
int find(int x, int y) //为了得到十六个格子对应的一维数组的下标
{ //将二维数组转化为一维数组
return x*4 + y;
}
int main()
{
int state = 0; //用一个数字来表示16个格子的状态,想明白的时候发现好神奇呀
for(int i = 0; i < 4; i ++)
{
string line;
cin >> line;
for(int j = 0; j < 4; j ++)
{
if(line[j] == '+') //如果为正,那么我们更改state状态值
{
state += 1 << find(i,j);
}
}
}
for(int i = 0; i < 4; i ++) //这三个for循环为了得到当与一个值异或的时候,要与他的每一行每一列异或
{ //每一行每一列放到一个数字里面,可以变成O1的复杂度
for(int j = 0; j < 4; j ++)
{
for(int k = 0; k < 4; k ++)
{
m1[i][j] += 1 << find(i,k); //每一行加起来
m1[i][j] += 1 << find(k,j); //每一列加起来
}
m1[i][j] -= 1 << find(i,j); //多了一个值再减去就好
}
}
vector<PII> ve;
for(int i = 0; i < 1 << 16; i ++)
{
int now = state;
vector<PII> v;
for(int j = 0; j < 16; j ++)
{
if(i >> j & 1)
{
int x = j/4, y = j%4;
now ^= m1[x][y];
v.push_back({x,y});
}
}
if(!now && (ve.empty() || ve.size() > v.size())) //如果当前这个操作完了变成0并且操作次数比上次小
{ //那么更新一下
ve = v;
}
}
cout << ve.size() << endl;
for(auto p : ve)
{
cout << p.first+1 << ' ' << p.second+1 << endl;
}
}