高斯消元模板
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; }