hdu 5755 2016 Multi-University Training Contest 3 Gambler Bo 高斯消元模3同余方程

http://acm.hdu.edu.cn/showproblem.php?pid=5755

题意:一个N*M的矩阵,改变一个格子,本身+2,四周+1.同时mod 3;问操作多少次,矩阵变为全0.输出次数和具体位置

由于影响是相互的,所以增广矩阵的系数a[t][t+1] 或者是 a[t+1][t]均可;只需注意往结果中添加位置时,x[i]表示要操作x[i]次,所以位置要重复添加x[i]次;

高斯消元时间复杂度为O(N3M3);

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 #define rep0(i,l,r) for(int i = (l);i < (r);i++)
  5 #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
  6 #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
  7 #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
  8 #define MS0(a) memset(a,0,sizeof(a))
  9 #define MS1(a) memset(a,-1,sizeof(a))
 10 #define MSi(a) memset(a,0x3f,sizeof(a))
 11 #define pb push_back
 12 #define A first
 13 #define B second
 14 #define MK make_pair
 15 #define inf 0x3f3f3f3f
 16 #define eps 1e-8
 17 #define zero(x) (((x)>0?(x):-(x))<eps)
 18 #define bitnum(a) __builtin_popcount(a)
 19 #define lowbit(x) (x&(-x))
 20 #define clear0 (0xFFFFFFFE)
 21 #define mod 3
 22 #define K(x) ((x)*(x))
 23 typedef pair<int,int> PII;
 24 typedef long long ll;
 25 typedef unsigned long long ull;
 26 template<typename T>
 27 void read1(T &m)
 28 {
 29     T x = 0,f = 1;char ch = getchar();
 30     while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
 31     while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
 32     m = x*f;
 33 }
 34 template<typename T>
 35 void read2(T &a,T &b){read1(a);read1(b);}
 36 template<typename T>
 37 void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
 38 template<typename T>
 39 void out(T a)
 40 {
 41     if(a>9) out(a/10);
 42     putchar(a%10+'0');
 43 }
 44 inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
 45 inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; }
 46 const int maxn = 907;
 47 int a[maxn][maxn];
 48 int x[maxn<<2];
 49 
 50 void init(int n,int m)
 51 {
 52     rep0(i,0,n) rep0(j,0,m){
 53         int t = i*m + j;
 54         a[t][t] = 2;
 55         if(i > 0) a[t - m][t] = 1;
 56         if(i < n-1) a[t + m][t] = 1;
 57         if(j > 0) a[t-1][t] = 1;
 58         if(j < m-1) a[t+1][t] = 1;
 59     }
 60 }
 61 
 62 int equ, var;
 63 int Gauss()
 64 {
 65     int mx, row, col;
 66     for(row = 0, col = 0; row < equ && col < var; row++, col++){
 67         mx = row;
 68         for(int i = row+1;i < equ;i++){
 69             if(abs(a[i][col]) > abs(a[mx][col])) mx = i;
 70         }
 71         if(a[mx][col] == 0) {
 72             row--;
 73             continue;
 74         }
 75         if(mx != row){
 76             for(int j = col;j < var + 1;j++)
 77                 swap(a[row][j], a[mx][j]);
 78         }
 79         for(int i = row+1;i < equ;i++){
 80             if(a[i][col]){
 81                 int LCM = lcm(abs(a[i][col]), abs(a[row][col]));
 82                 int ta = LCM/abs(a[i][col]), tb = LCM/abs(a[row][col]);
 83                 if(a[i][col] * a[row][col] < 0) tb = -tb;
 84                 for(int j = col; j < var+1;j++)
 85                     a[i][j] = ((a[i][j]*ta - a[row][j]*tb)%mod+mod)%mod;
 86             }
 87         }
 88     }
 89    
 90     for(int i = var-1; i >= 0; i--){
 91         if(a[i][i] == 0) continue;
 92         int tmp = a[i][var];
 93         for(int j = i+1;j < var;j++){
 94             if(a[i][j]){
 95                 tmp -= a[i][j]*x[j];
 96                 tmp = (tmp%mod + mod)% mod;
 97             }
 98         }
 99         x[i] = (tmp*a[i][i])% mod;
100     }
101     return 0;
102 }
103 vector<int> vec;
104 int main()
105 {
106     //freopen("data.txt","r",stdin);
107     //freopen("out.txt","w",stdout);
108     int T, kase = 1;
109     scanf("%d",&T);
110     while(T--){
111         int n, m, t;
112         read2(n,m);
113         equ = n*m, var = n*m;
114         MS0(a);
115         rep0(i,0,n) rep0(j,0,m) read1(t), a[i*m+j][var] = (mod-t)%mod;
116         init(n,m);
117 
118         Gauss();
119         vec.clear();
120         rep0(i,0,var)  while(x[i]--) vec.pb(i);
121         out(vec.size());puts("");
122         rep0(i,0,vec.size()) printf("%d %d\n",vec[i]/m + 1, vec[i]%m + 1);
123     }
124     return 0;
125 }

 

posted @ 2016-07-27 22:02  hxer  阅读(357)  评论(0编辑  收藏  举报