POJ 1830 开关问题 高斯消元
http://poj.org/problem?id=1830
题意:汉语哎。。。
建方程有个资料 http://blog.csdn.net/shiren_Bod/article/details/5766907
X1*A(1,1)1+X2*A(1,2)1+X3*A(1,3)1+…………X30*A(30,30)1=L1; mod 2
X1*A(1,1)2+X2*A(1,2)2+X3*A(1,3)2+…………X30*A(30,30)2=L2; mod 2
X1*A(1,1)3+X2*A(1,2)3+X3*A(1,3)3+…………X30*A(30,30)3=L3 mod 2
…….
…….
…….
X1*A(1,1)30+X2*A(1,2)30+X3*A(1,3)30+…………X30*A(30,30)30=L30; mod 2
其中A(i,j)k 表示列向量A中第K个元素
还有一个一般 高斯消元的模版 http://www.acmwiki.com/index.php?doc-view-298.htm
const int num = 100;
double matrix[num][num + 1]; //系数矩阵,从0开始
double ans[num]; //结果数组
void exchange_col(int p1,int p2,int n) //交换p1行和p2行的所有数据
{
double t;
int i;
for(i = 0 ; i <= n ; i++)
t = matrix[p1][i],matrix[p1][i] = matrix[p2][i],matrix[p2][i] = t;
}
bool gauss(int n) //求解系数矩阵为n的线性方程组
{
int i,j,k;
int p;
double r;
for(i = 0 ; i < n - 1 ; i++) {
p = i;
for(j = i + 1 ; j < n ; j++) { //寻找i列最大值位置
if(matrix[j][i] > matrix[p][i])
p = j;
}
if(matrix[p][i] == 0) return false;
if(p != i) exchange_col(i,p,n);
for(j = i + 1 ; j < n ; j++) { //剩余列进行消元
r = matrix[j][i] / matrix[i][i];
for(k = i ; k <= n ; k++)
matrix[j][k] -= r * matrix[i][k];
}
}
for(i = n - 1 ; i >= 0 ; i--) { //获得结果
ans[i] = matrix[i][n];
for(j = n - 1 ; j > i ; j--)
ans[i] -= matrix[i][j] * ans[j];
ans[i] /= matrix[i][i];
}
return true;
}
本题代码:
#include<iostream> #include<cstdio> #include<cstring> #define nMAX 31 using namespace std; int map[nMAX][nMAX],begin[nMAX],end[nMAX]; int n; void gauss() { int i,j,k,p,t; for(i=0,j=0;i<n,j<n;i++,j++)//i行,j列 { for(p=i;p<n;p++)//找绝对值最大的 { if(map[p][j]!=0)break; } if(p==n){i--;continue;}//还是从当前行 if(p!=i)//交换行 { for(k=0;k<=n;k++) { t=map[p][k]; map[p][k]=map[i][k]; map[i][k]=t; } } for(k=i+1;k<n;k++) { if(!map[k][j])continue; for(t=j;t<=n;t++) map[k][t]^=map[i][t]; } } for(k=i;k<n;k++)//因为for循环中有个i++ if(map[k][n]!=0) { printf("Oh,it's impossible~!!\n"); return ; } printf("%d\n",(1<<(n-i))); } int main() { int CASE,i,j; scanf("%d",&CASE); while(CASE--) { scanf("%d",&n); memset(map,0,sizeof(map)); for(i=0;i<n;i++) scanf("%d",&begin[i]); for(i=0;i<n;i++) { scanf("%d",&end[i]); map[i][n]=begin[i]^end[i]; } while(~scanf("%d%d",&i,&j)) { if(i==0&&j==0)break; map[j-1][i-1]=1; } for(i=0;i<n;i++) map[i][i]=1; gauss(); } return 0; }