给n*m的方格, 每个格子有值{0, 1, 2}。 然后可以对格子进行操作, 如果选择了一个格子, 那么这个格子的值+2, 这个格子上下左右的格子+1, 并且模3。
问你将所有格子变成0的操作方法。
其实就是一个模3的方程组, 高斯消元就可以了。 不知道为什么昨天比赛就是想不到......
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <complex> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef complex <double> cmx; typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 3; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; int a[901][902]; int n, b[902], x[902], m; int gcd(int a, int b) { return b?gcd(b, a%b):a; } int lcm(int a, int b) { return a/gcd(a, b)*b; } ll inv(ll a, ll m) { if(a == 1) return 1; return inv(m%a, m)*(m-m/a)%m; } int gauss(int equ, int var) { int max_r, col, k; for(k = 0, col = 0; k < equ && col < var; k++, col++) { max_r = k; for(int i = k + 1; i < equ; i ++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i; } if(a[max_r][col] == 0) { k--; continue; } if(max_r != k) { for(int j = col; j < var+1; j++) { swap(a[k][j], a[max_r][j]); } } for(int i = k + 1; i < equ; i++) { if(a[i][col]) { int LCM = lcm(abs(a[i][col]), abs(a[k][col])); int ta = LCM/abs(a[i][col]); int tb = LCM/abs(a[k][col]); if(a[i][col] * a[k][col] < 0) tb = -tb; for(int j = col; j < var+1; j++) { a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%mod+mod)%mod; } } } for(int i = var-1; i >= 0; i--) { int tmp = a[i][var]; for(int j = i+1; j < var; j++) { if(a[i][j]) { tmp -= a[i][j]*x[j]; tmp = (tmp%mod+mod)%mod; } } x[i] = a[i][i]*tmp%mod; } } } int check(int x) { return x >=0 && x < n*m; } int main() { int t; cin>>t; while(t--) { scanf("%d%d", &n, &m); for(int i = 0; i < n*m; i++) { scanf("%d", &b[i]); } mem(x); mem(a); for(int i = 0; i < n*m; i++) { int u = i-m, d = i+m; int l = i-1, r = i+1; if(check(u)) { a[i][u] = 1; } if(check(d)) { a[i][d] = 1; } if(check(l)&&i%m!=0) { a[i][l] = 1; } if(check(r)&&(i+1)%m!=0) { a[i][r] = 1; } a[i][i] = 2; a[i][n*m] = (3-b[i])%3; } n *= m; gauss(n, n); int cnt = 0; for(int i = 0; i < n; i++) { if(x[i]) cnt += x[i]; } printf("%d\n", cnt); for(int i = 0; i < n; i++) { while(x[i]) { printf("%d %d\n", i/m+1, i%m+1); x[i]--; } } } return 0; }