2016MUTC3-1004 Gambler Bo

来源:互联网 发布:重庆软件开发学院 编辑:程序博客网 时间:2024/05/14 03:42

模3下的高斯消元,保证一定有解

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <vector>using namespace std;typedef int LL;const int N=30+5;const int M=900+5;int c[N][N],n,m;int a[M][M],b[M],d[M];int Hash(int x,int y){return (x-1)*m+y;}int gcd(int a,int b){return b==0?a:gcd(b,a%b);}void Debug(){    printf("********************\n");    for (int i=1;i<=n*m;i++){        for (int j=1;j<=n*m;j++)printf("%d ",a[i][j]);        printf("%d\n",b[i]);    }    printf("********************\n");}void work(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)scanf("%d",&c[i][j]);    memset(a,0,sizeof a);    int cnt=0;    for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){        cnt++;        if (i>1)a[cnt][Hash(i-1,j)]=1;        if (j>1)a[cnt][Hash(i,j-1)]=1;        a[cnt][Hash(i,j)]=2;        if (j<m)a[cnt][Hash(i,j+1)]=1;        if (i<n)a[cnt][Hash(i+1,j)]=1;        b[Hash(i,j)]=(3-c[i][j])%3;    }    //Debug();    for (int j=1;j<=cnt;j++){//枚举列        int id=j;        for (int i=j+1;i<=cnt;i++)if (a[i][j]>a[id][j]){id=i;break;}//a数组肯定为非负        if (a[id][j]==0){continue;}        if (id!=j){            for (int k=1;k<=cnt;k++)swap(a[id][k],a[j][k]);            swap(b[j],b[id]);        }        for (int i=j+1;i<=cnt;i++)if (a[i][j]){            int t1=a[i][j],t2=a[j][j];            int g=gcd(abs(t1),abs(t2)); t1/=g;t2/=g;            for (int k=j;k<=cnt;k++){                a[i][k]=((a[i][k]*t2-a[j][k]*t1)%3+3)%3;            }            b[i]=((b[i]*t2-b[j]*t1)%3+3)%3;        }        //Debug();    }    int tot=0;    for (int j=cnt;j>=1;j--){        if (a[j][j]==0){d[j]=0;continue;}        int Now=b[j];        for (int k=j+1;k<=cnt;k++)Now=((Now-d[k]*a[j][k])%3+3)%3;        d[j]=((Now*a[j][j])%3+3)%3;//1的逆元是1,2的逆元是2        tot+=d[j];    }    printf("%d\n",tot);    for (int i=1;i<=cnt;i++)while (d[i]>0){        printf("%d %d\n",(i+m-1)/m,i-(i-1)/m*m);        d[i]--;    }}int main(){    //freopen("1.txt","r",stdin);    int Case;scanf("%d",&Case);    while (Case--)work();    return 0;}


0 0
原创粉丝点击