列出模方程,高斯消元解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define N 1005
#define M 400200
#define U 1000000
#define inf 0x3f3f3f3f
#define mod 3
#define LL long long
#define ULL unsigned long long
#define ls (i << 1)
#define rs (ls | 1)
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define MP make_pair
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b){
return a * b / gcd(a, b);
}
int a[N][N], x[N], v[N][N];
vector<int> ans;
int d[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
void Gauss(int n){
int k, col;
for(k = 0, col = 0; k < n && col < n; ++k, ++col){
int mx = k;
for(int i = k + 1; i < n; ++i)
if(abs(a[i][col]) > abs(a[mx][col]))
mx = i;
if(k != mx){
for(int i = col; i < n; ++i)
swap(a[k][i], a[mx][i]);
swap(x[k], x[mx]);
}
if(a[k][col] == 0){
k--; continue;
}
for(int i = k + 1; i < n; ++i){
if(a[i][col]){
int LCM = lcm(a[i][col], a[k][col]);
int t1 = LCM / a[i][col], t2 = LCM / a[k][col];
for(int j = col; j < n; ++j)
a[i][j] = ((a[i][j] * t1 - a[k][j] * t2) % mod + mod) % mod;
x[i] = ((x[i] * t1 - x[k] * t2) % mod + mod) % mod;
}
}
}
for(int i = k - 1; i >= 0; --i){
for(int j = i + 1; j < n; ++j)
x[i] = ((x[i] - x[j] * a[i][j]) % mod + mod) % mod;
x[i] = x[i] * a[i][i] % mod;
if(x[i] < 0) x[i] += mod;
}
}
int n, m;
bool check(int x, int y){
return x >= 0 && x < n && y >= 0 && y < m;
}
int main(){
int cas;
scanf("%d", &cas);
while(cas--){
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
scanf("%d", &v[i][j]);
memset(x, 0, sizeof x);
memset(a, 0, sizeof a);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j){
int cur = i * m + j;
a[cur][cur] = 2;
for(int k = 0; k < 4; ++k){
int nx = i + d[k][0], ny = j + d[k][1];
if(check(nx, ny)){
int nxt = nx * m + ny;
a[cur][nxt] = 1;
}
}
x[cur] = (3 - v[i][j]) % 3;
}
Gauss(n * m);
ans.clear();
for(int i = 0; i < n * m; ++i){
while(x[i]){
ans.push_back(i);
x[i]--;
}
}
printf("%d\n", (int)ans.size());
for(int i = 0; i < ans.size(); ++i){
int r = ans[i] / m;
int c = ans[i] % m;
printf("%d %d\n", r + 1, c + 1);
}
}
return 0;
}