• 高斯消元模板


    http://poj.org/problem?id=1753

    View Code
    struct GaussE {
        int a[MM][MM];
        int x[MM]; // 解集
        int equ, var;
        int free_x[MM]; // 记录不确定的变元.
        //初始化
        GaussE(int e,int v):equ(e), var(v) {}
        void reset() {
            memset(a,0,sizeof(a));
            memset(x,0,sizeof(x));
            memset(free_x,0,sizeof(free_x));
        }
        //重写(),方便存取
        int& operator() (int i,int j) {return a[i][j];}
        //debug
        void out() {
            int i,j,k;
            for(i=0;i<equ;i++)    {
                for(j=0;j<(var+1);j++) {
                    printf("%d ",a[i][j]);
                }
                printf("\n");
            }
            printf("\n");
        }
    // 有equ个方程,var个变元 增广阵行数为equ
    //分别为0到equ-1,列数为var+1,分别为0到var.
    //传入equ, var (var列存方程组的解)
        int Gauss() {
            int i,j,k,col,row,ta,tb, temp; 
            int max_r, LCM, ans, mm=0;
            int free_x_num, free_index, sum, tt;  
    
            for(row=col=0; row<equ && col<var; row++,col++) { 
                max_r=row;
                for(i=row+1;i<equ;i++) {
                    if(f_abs(a[i][col])>f_abs(a[max_r][col])) max_r=i;
                }
                if(max_r!=row) {
                    for(j=row; j<var+1; j++) swap(a[row][j],a[max_r][j]);
                }
                if(a[row][col]==0) { 
                    row--; 
                    free_x[mm++]=col;
                    continue;
                }
                for(i=row+1; i<equ; i++) { 
                    if(a[i][col]!=0) {
            //         LCM=lcm(f_abs(a[i][col]),f_abs(a[row][col]));
            //         ta=LCM/f_abs(a[i][col]), tb=LCM/f_abs(a[row][col]);
            //         if(a[i][col]*a[row][col]<0) tb=-tb; 
                    for(j=col; j<var+1; j++) {
            //            a[i][j] = a[i][j] * ta - a[row][j] * tb;
                        a[i][j]^=a[row][j];
                     }
                    }
                }
            }
           //无解
            for(i=row; i<equ; i++) if (a[i][col]!=0) return -1;
            //无穷解,变元个数为var-row
            if(row<var)  return var-row;     
            //唯一解
            return 0;
        }
        int gao(int row) {
            int i,j,k,sum,tt;
            int res=-1, state=1<<(var-row); //自由变元枚举
            for(i=0;i<state;i++) {
                sum=0, tt=i; 
                for(j=0;j<(var-row);j++) {
                    x[free_x[j]]=(tt&1);
                    sum+=x[free_x[j]];
                    tt>>=1;
                }
                
                for(j=row-1;j>=0;j--) {
                    x[j]=a[j][var];
                    for(k=j+1;k<var;k++) {
                        if(a[j][k]!=0) x[j]^=x[k];
                    }
                    sum+=x[j];
                }
                if(res==-1||res>sum) res=sum;
            }
            return res;
        }
    };
    
    bool ok(int x,int y) {
        return x>=0 && x<N && y>=0 && y<N;
    }
    
    void get_data() {
        int i,j,k;
        N=4;
        for(i=0;i<N;i++) scanf("%s",str[i]);
    }
    void solve() {
        int i,j,k, limit=N*N, tmp, tx,ty, ans, ff;
        GaussE gauss(limit,limit);
        
        gauss.reset();
        for(i=0;i<N;i++) {
            for(j=0;j<N;j++) {
                tmp=i*N+j;
                gauss(tmp,limit)=(str[i][j]=='b');
                gauss(tmp,tmp)=1;
                for(k=0;k<4;k++) {
                    tx=i+dx[k], ty=j+dy[k];
                    if(ok(tx,ty)) gauss(tmp,tx*N+ty)=1;
                }
            }
        }
        ans=gauss.Gauss();
        if(ans!=-1) ans=gauss.gao(limit-ans);
        
        gauss.reset();
        for(i=0;i<N;i++) {
            for(j=0;j<N;j++) {
                tmp=i*N+j;
                gauss(tmp,limit)=(str[i][j]=='w');
                gauss(tmp,tmp)=1;
                for(k=0;k<4;k++) {
                    tx=i+dx[k], ty=j+dy[k];
                    if(ok(tx,ty)) gauss(tmp,tx*N+ty)=1;
                }
            }
        }
        tmp=gauss.Gauss();
        if(tmp!=-1) tmp=gauss.gao(limit-tmp);
        
        if(tmp==-1&&ans==-1) puts("Impossible");
        else {
            if(tmp>=0&&ans>=0) printf("%d\n",f_min(tmp,ans));
            else if(tmp==-1) printf("%d\n", ans);
            else printf("%d\n",tmp);
        }
    }
    
    int main() {
        //    int ca;  scanf("%d",&ca);
        get_data(),solve();
        return 0;
    }
  • 相关阅读:
    洛谷P1306 斐波那契公约数
    Codevs 1688 求逆序对(权值线段树)
    poj1006 Biorhythms
    2017-9-2 NOIP模拟赛
    洛谷P1633 二进制
    洛谷P2513 [HAOI2009]逆序对数列
    洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower
    洛谷P2285 [HNOI2004]打鼹鼠
    2017-8-31 NOIP模拟赛
    洛谷P2134 百日旅行
  • 原文地址:https://www.cnblogs.com/zhang1107/p/3022303.html
Copyright © 2020-2023  润新知