codeforce gym 2011-2012 Waterloo 高斯消元:构造01矩阵,使1的相邻4个矩阵+自身为偶数
首先要知道,如果第一行可以确定那么下面的n-1行都可以确定。
如何确定第一行,假设第一行m个数,然后迭代算到n+1行,根据都为0可以得到m个方程,然后高斯异或解方程,自由元地方全部放1即可,就可以把第一行求出来
继而balabaka可以都算出来==
似乎我的guass放自由元部分略繁琐,不急马上搞一个漂亮的模板TUT
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 int g[45][45],a[45][45],n,m,pre[45][45],b[45][45]; 5 using namespace std; 6 int guass() 7 { 8 int row,col,i,j; 9 for (row=1,col=1;col<=m;col++) 10 { 11 for (i=row;i<=m;i++) 12 if (g[i][col]) break; 13 if (i>m) continue; 14 if (i!=row) 15 for (j=col;j<=m;j++) swap(g[i][j],g[row][j]); 16 for (i=row+1;i<=m;i++) 17 if (g[i][col]) 18 for (j=col;j<=m;j++) 19 g[i][j]^=g[row][j]; 20 row++; 21 } 22 /* for (i=1;i<=m;i++) 23 { 24 for (j=1;j<m;j++) printf("%d ",g[i][j]); 25 printf("%d\n",g[i][m]); 26 } 27 printf("---------------\n");*/ 28 int x,tmp; 29 for (i=1;i<=m;i++) a[1][i]=1; 30 for (i=1;i<=m;i++) 31 { 32 for (j=1;j<=m;j++) 33 if (g[i][j]) 34 { 35 a[1][j]=0; 36 break; 37 } 38 } 39 for (i=m;i>=1;i--) 40 { 41 tmp=0; 42 for (j=1;j<=m;j++) 43 if (g[i][j]) 44 { 45 tmp=j; 46 break; 47 } 48 if (tmp==0) continue; 49 x=0; 50 for (j=tmp+1;j<=m;j++) 51 if (g[i][j]) x^=a[1][j]; 52 a[1][tmp]=x; 53 } 54 55 } 56 int main() 57 { 58 int T,i,j,k; 59 scanf("%d",&T); 60 while (T--) 61 { 62 scanf("%d%d",&n,&m); 63 memset(a,0,sizeof(a)); 64 memset(g,0,sizeof(g)); 65 memset(pre,0,sizeof(pre)); 66 for (i=1;i<=m;i++) g[i][i]=1; 67 for (i=1;i<=n;i++) 68 { 69 for (j=1;j<=m;j++) 70 for (k=1;k<=m;k++) 71 b[j][k]=(g[j][k]^g[j-1][k]^g[j+1][k]^pre[j][k]); 72 for (j=1;j<=m;j++) 73 for (k=1;k<=m;k++) 74 { 75 pre[j][k]=g[j][k]; 76 g[j][k]=b[j][k]; 77 } 78 } 79 guass(); 80 for (i=2;i<=n;i++) 81 for (j=1;j<=m;j++) 82 a[i][j]=(a[i-1][j]^a[i-1][j-1]^a[i-1][j+1]^a[i-2][j]); 83 for (i=1;i<=n;i++) 84 { 85 for (j=1;j<m;j++) printf("%d ",a[i][j]); 86 printf("%d\n",a[i][m]); 87 } 88 } 89 return 0; 90 }