http://hihocoder.com/contest/hiho57/problem/1
高斯消元的变种,因为图很小所以而且每一个小格子都得为1,那么就把图中对某个小格子有作用的点标记起来,而他们的共同作用次数为奇数的话,小格子的状态变化,反之不变,
注意这里在处理矩阵时,对于第i列的数字如果原本就为0的话,就不用处理,否则会错误
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int Mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double eps = 0.00000001;
const int INF = 0x3f3f3f3f;
struct Change{
int x, y;
bool friend operator < (Change a, Change b){
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
}ch[maxn];
int a[35][35];
int b[35], x[35];
bool manySolution = false, noSolution = false;
void Swap(int i, int j) {
for (int k = 1; k <= 30; k ++)
swap(a[i][k], a[j][k]);
swap(b[i], b[j]);
}
bool Check(int i) {
bool vis = false;
for (int k = 1; k <= 30; k ++) {
if(a[i][k]) vis = true;
}
if(!vis && b[i]) return false;
return true;
}
void GS() {
for (int i = 1; i <= 30; i ++) {
bool vis = false;
for (int j = i; j <= 30; j ++) {
if(a[i][j] != 0) {
Swap(i, j);
vis = true;
break;
}
}
if(!vis) {
manySolution = true;
continue;
}
for (int j = i + 1; j <= 30; j ++) {
if(a[j][i]) {//如果原本就为0,就不处理
for (int k = i; k <= 30; k ++)
a[j][k] = a[j][k] ^ a[i][k];
b[j] = b[j] ^ b[i];
}
}
}
for (int i = 1; i <= 30; i ++) {
if(!Check(i)) {
noSolution = true;
return ;
}
}
for (int i = 30; i >= 1; i --) {
for (int j = i + 1; j <= 30; j ++) {
b[i] = b[i] ^ (a[i][j] * x[j]);
a[i][j] = 0;
}
x[i] = b[i] / a[i][i];
}
}
int main()
{
char c[35][35];
for (int i = 1; i <= 5; i ++)
scanf("%s", c[i]);
for (int i = 1; i <= 5; i ++)
for (int j = 1; j <= 6; j ++) {
b[(i - 1) * 6 + j] = c[i][j - 1] - '0';
b[(i - 1) * 6 + j] ^= 1;
}
memset(a, 0, sizeof(a));
for (int i = 1; i <= 30; i ++) {
a[i][i] = 1;
if(i + 1 <= 30 && i + 1 >= 1 && i % 6 != 0) a[i][i + 1] = 1;
if(i - 1 <= 30 && i - 1 >= 1 && i % 6 != 1) a[i][i - 1] = 1;
if(i + 6 <= 30 && i + 6 >= 1) a[i][i + 6] = 1;
if(i - 6 <= 30 && i - 6 >= 1) a[i][i - 6] = 1;
}
GS();
int cnt = 0;
for (int i = 1; i <= 30; i ++) {
if(x[i]) {
if(i % 6) {
ch[cnt ++] = Change{i/6 + 1, i % 6};
}else {
ch[cnt ++] = Change{i/6, 6};
}
}
}
sort(ch, ch +cnt);
cout << cnt << endl;
for (int i = 0; i < cnt; i ++)
cout << ch[i].x << " " << ch[i].y << endl;
return 0;
}