http://acm.hdu.edu.cn/showproblem.php?pid=5755
题意:
n*m矩阵,每个格有数字0/1/2
每选择一个格子,这个格子+2,4方向相邻格子+1
如何选择格子,可以使每个格子的数最后 %3=0
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mod=3; int n,m,t; int a[901][901]; int x[901]; int turn(int i,int j) { return (i-1)*m+j-1; } int getgcd(int a,int b) { return !b ? a : getgcd(b,a%b); } int getlcm(int a,int b) { return a*b/getgcd(a,b); } void gauss() { int equ=n*m,var=n*m; int i,j,k; int max_r,col; int ta,tb; int lcm; int tmp; for(k=0,col=0;k<equ && col<var;++k,++col) { max_r=k; for(i=k+1;i<equ;++i) if(abs(a[i][col])>abs(a[max_r][col])) max_r=i; if(!a[max_r][col]) { --k; continue; } if(max_r!=k) swap(a[k],a[max_r]); for(i=k+1;i<equ;++i) if(a[i][col]) { lcm=getlcm(abs(a[i][col]),abs(a[k][col])); ta=lcm/abs(a[i][col]); tb=lcm/abs(a[k][col]); if(a[i][col]*a[k][col]<0) tb=-tb; for(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 main() { int T; scanf("%d",&T); int xi,tmp; int ans; while(T--) { memset(a,0,sizeof(a)); scanf("%d%d",&n,&m); t=n*m; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { scanf("%d",&xi); a[turn(i,j)][t]=3-xi; } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { tmp=turn(i,j); a[tmp][tmp]=2; if(i>1) a[turn(i-1,j)][tmp]=1; if(i<n) a[turn(i+1,j)][tmp]=1; if(j>1) a[turn(i,j-1)][tmp]=1; if(j<m) a[turn(i,j+1)][tmp]=1; } gauss(); ans=0; for(int i=0;i<t;++i) ans+=x[i]; printf("%d\n",ans); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { tmp=turn(i,j); if(x[tmp]) while(x[tmp]--) printf("%d %d\n",i,j); } } }