Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 676 Accepted Submission(s): 274
Special Judge
Problem Description
Gambler Bo is very proficient in a matrix game.
You have a M times.
You have a M times.
Input
First line, an integer 30, the matrix is random and guarantee that there is at least one operation solution.
Output
For each test, first line contains an integer ) describing the operation cell.
The answer may not be unique, you can output any one.
The answer may not be unique, you can output any one.
Sample Input
2
2 3
2 1 2
0 2 0
3 3
1 0 1
0 1 0
1 0 1
Sample Output
1
1 2
5
1 1
1 3
2 2
3 1
3 3
用高斯消元法可解。每个位置的结果可以由他本身和四个方向上的变化决定。
那么设横坐标为每个位置上的数值(一共n*m个位置),纵坐标为对这个数值的影响。A[i][j]=1表示j使i+1 ,A[i][j]=2表示j使i+2 同理A[i][j]=0表示j使i+0
那么就可以构造一个(n*m) *(n*m)的方阵。设X为(n*m)*1的矩阵表示n*m个位置每个位置增加的次数, B为(n*m)*1的矩阵,B与题目中给的值有关,这里表示增加多少使得终态为0.
AX=B,解出X矩阵就行了..
卧槽 好烦 写的这么乱,不过还是挺好理解的....
/* *********************************************** Author :guanjun Created Time :2016/7/28 8:36:24 File Name :hdu5755.cpp ************************************************ */ #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <iomanip> #include <list> #include <deque> #include <stack> #define ull unsigned long long #define ll long long #define mod 3 #define INF 0x3f3f3f3f #define maxn 10010 #define cle(a) memset(a,0,sizeof(a)) const ull inf = 1LL << 61; const double eps=1e-5; using namespace std; int a[1100][1100]; int A[1100][1100]; int x[1100]; int dir[4][2]={1,0,0,1,0,-1,-1,0}; int exgcd(int a,int b,int &x,int &y){ if(!b){x = 1; y = 0; return a;} else{ int r = exgcd(b,a%b,y,x); y -= x * (a/b); return r; } } int lcm(int a,int b){ int x = 0, y =0; return a / exgcd(a,b,x,y) * b; } void Gauss(int n,int m){ int r,c; //列主元消去 for(r=0,c=0;r<n&&c<m;c++){ int maxr=r; for(int i=r+1;i<n;i++)if(abs(A[i][c])>abs(A[maxr][c]))maxr=i; if(maxr!=r)for(int i=c;i<=m;i++)swap(A[r][i],A[maxr][i]); if(!A[r][c])continue; for(int i=r+1;i<n;i++)if(A[i][c]){ int d=lcm(A[i][c],A[r][c]); int t1=d/A[i][c],t2=d/A[r][c]; for(int j=c;j<=m;j++) A[i][j]=((A[i][j]*t1-A[r][j]*t2)%mod+mod)%mod; } r++; } for(int i=r;i<n;i++)if(A[i][m])return ; //从下到上 for(int i=r-1;i>=0;i--){ x[i]=A[i][m]; for(int j=i+1;j<m;j++) x[i]=((x[i]-A[i][j]*x[j])%mod+mod)%mod; int x1=0,y1=0; //这里是用exgcd求逆元,也可以用费马小定理求,如果mod是素数 int d = exgcd(A[i][i],mod,x1,y1); //cout<<"d "<<d<<endl; x1=((x1%mod)+mod)%mod; x[i]=x[i]*x1%mod; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif //freopen("out.txt","w",stdout); int t,n,m; cin>>t; while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ for(int j=0;j<m;j++)scanf("%d",&a[i][j]); } cle(A); for(int i=0;i<n*m;i++){ A[i][i]=2;//选择自己 加2 int r=i/m;int c=i%m; for(int j=0;j<4;j++){ int x=r+dir[j][0]; int y=c+dir[j][1]; if(x<n&&x>=0&&y<m&&y>=0)A[i][x*m+y]=1;//四个方向+1 } A[i][n*m]=(3-a[r][c])%3;//每个位置需要加的数 和初始状态有关 } Gauss(n*m,n*m); int cnt=0; vector<int>v; for(int i=0;i<n*m;i++){ while(x[i]){ x[i]--; v.push_back(i); } } printf("%d\n",v.size()); for(int i=0;i<v.size();i++){ int r=v[i]/m; int c=v[i]%m; r++,c++; printf("%d %d\n",r,c); } } return 0; }