POJ - 1222 高斯消元基础题,解异或方程组
题意:给出5行6列的矩阵,每个位置有一个数,0或1。在(i,j)的位置按一下,则它自身和它上下左右的位置都要反转,要通过这样的操作把所有位置都变为0。输出一个5行6列的矩阵,1表示这个位置按了,0表示没按。
总结:高斯消元,还没有完全弄明白,参考大神博客强行码了一发。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// POJ - 1222 #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<bitset> #include<vector> #include<set> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 40; int a[N][N], ans[N]; //ans[]为解集 int gauss(int equ, int var) //有equ个方程,var个变元,增广矩阵行数[0, equ - 1],列数[0, var] { FF(i,0,var) ans[i]=0; //初始化 int col=0, row=0, maxRow; //下面转换为阶梯矩阵,col表示当前正在处理的这一列,maxR表示当前这个列中元素绝对值最大的行 for( ; row<equ && col<var; row++, col++) { //枚举当前正在处理的行,找到该col列元素绝对值最大的那行与第k行交换 maxRow=row; F(i,row+1,equ) { if(abs(a[maxRow][col]< abs(a[i][col]))) maxRow=i; } if(maxRow!=row) { //与第row行交换 F(j,row,var+1) { swap(a[row][j], a[maxRow][j]); } } if(a[row][col]==0) { //说明该col列第row行以下全是0,处理当前行的下一列 row--; continue; } F(i,row+1,equ) { //枚举要删的行 if(a[i][col]!=0) { F(j,col,var+1) { a[i][j]^= a[row][j]; } } } } for(int i=var-1; i>=0; i--) { ans[i]= a[i][var]; F(j,i+1,var) { ans[i]^= (a[i][j]&&ans[j]); } } return 0; } int main() { int n; cin>>n; FF(cas,1,n) { mes(a,0); F(i,0,30) cin>>a[i][30]; F(i,0,5) F(j,0,6) { //构建系数矩阵 int t=i*6+j; a[t][t]=1; if(i>0) a[(i-1)*6+j][t]=1; //这里不太懂为什么 if(i<4) a[(i+1)*6+j][t]=1; if(j>0) a[i*6+j-1][t]=1; if(j<5) a[i*6+j+1][t]=1; } gauss(30,30); printf("PUZZLE #%d\n", cas); F(i,0,30) { cout<<ans[i]; if((i+1)%6==0 ) cout<<endl; else cout<<" "; } } return 0; }