Live2d Test Env

HDU - 5755:Gambler Bo (开关问题,%3意义下的高斯消元)

pro:给定N*M的矩阵,每次操作一个位置,它会增加2,周围4个位置会增加1。给定初始状态,求一种方案,使得最后的数都为0;(%3意义下。

sol:(N*M)^3的复杂度的居然过了。          好像标程是M^3的,因为第一排确定了,后面的都确定了。所以我们只要设关于第一排的方程,那么跑下来,第N+1排的都为0,则合法。

(此题由于3的特殊性,x关于3的逆元=x;所以不用求逆元

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1010;
int a[maxn][maxn],ans[maxn];
int x[4]={0,0,1,-1};
int y[4]={1,-1,0,0};
void Guass(int N)
{
    rep(i,0,N-1){
        int t=i;
        rep(j,i+1,N-1) if(a[j][i]>a[t][i]) t=j;
        if(i!=t) rep(j,i,N) swap(a[i][j],a[t][j]);
        if(!a[i][i]) continue;
        rep(j,i+1,N-1){
            if(!a[j][i]) continue;
                int t1=a[i][i],t2=a[j][i];//保留,不能直接带进去
                rep(k,i,N)
                  a[j][k]=((a[j][k]*t1-a[i][k]*t2)%3+3)%3;
        }
    }
    for(int i=N-1;i>=0;i--){
        a[i][N]=a[i][N]*a[i][i]%3;
        rep(j,0,i-1)
            a[j][N]=((a[j][N]-a[i][N]*a[j][i])%3+3)%3;
    }
}
int main()
{
    int T,N,M,S,t,p;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M); S=N*M;
        rep(i,0,S) rep(j,0,S) a[i][j]=0;
        rep(i,0,N-1) rep(j,0,M-1){
            t=i*M+j;
            scanf("%d",&a[t][S]);
            a[t][S]=3-a[t][S];
        }
        rep(i,0,S-1) a[i][i]=2;
        rep(i,0,N-1)
         rep(j,0,M-1){
            t=i*M+j;
            rep(k,0,3) {
                if(i+x[k]>=0&&i+x[k]<N&&j+y[k]>=0&&j+y[k]<M){
                    a[(i+x[k])*M+j+y[k]][t]=1;
                }
            }
        }
        Guass(S);
        int res=0;
        rep(i,0,S-1) res+=a[i][S];
        printf("%d\n",res);
        rep(i,0,S-1){
            p=i/M+1; t=i%M+1;
            if(a[i][S]) printf("%d %d\n",p,t);
            if(a[i][S]==2) printf("%d %d\n",p,t);
        }
    }
    return 0;
}

 

posted @ 2019-04-25 15:56  nimphy  阅读(290)  评论(0编辑  收藏  举报