浮点高斯消元
高斯消元的思想小学就会,细节看代码吧
db a[200][200];
void solve() {
int n;
cin>>n;
rep(i,0,n-1){
rep(j,0,n){
cin>>a[i][j];
}
}
int r,c;
for(r=0,c=0;c<n;c++){
int t=r;
//找到这一列系数,绝对值最大的行
for(int i=r;i<n;i++){
if(fabs(a[i][c])>fabs(a[t][c])){
t=i;
}
}
//这一列都是零,直接跳过
if(fabs(a[t][c])<eps){
continue;
}
//把最大这一行换到第r行
for(int j=c;j<=n;j++){
swap(a[t][j],a[r][j]);
}
//这一行的第c列系数消成1,这个方程等号两边同除
for(int j=n;j>=c;j--){
a[r][j]/=a[r][c];
}
for(int i=r+1;i<n;i++){
if(fabs(a[i][c])>eps){
//用第r行把后面的行,第c列都消成0
//把第r行,乘上一个比例,也就是a[i][c],再从第i行减去
for(int j=n;j>=c;j--){
a[i][j]-=a[r][j]*a[i][c];
}
}
}
r++;
//处理完了一行
}
//矩阵的秩不够,要么无解,要么无穷解,反正没有唯一解
if(r<n){
cout<<"No Solution\n";
}
else{
//此时我们已经把矩阵变成上三角了
//从下往上回代即可变成单位矩阵
for(int i=n-1;i>=0;i--){
for(int j=i+1;j<n;j++){
a[i][n]-=a[i][j]*a[j][n];
}
}
for(int i=0;i<n;i++){
cout<<fixed<<setprecision(2)<<a[i][n]<<'\n';
}
}
}
异或
主体思路类似地,进行的运算略不同
void solve() {
int n,m;
cin>>n>>m;
vvi a(n+1,vi(n+2));
rep(i,1,m){
int u,v;
cin>>u>>v;
a[u][v]=a[v][u]=1;
}
int r=1;
rep(c,1,n){
int t=r;
//找到最大的一行,交换到第r行
rep(i,r+1,n){
if(a[i][c]>a[t][c]){
t=i;
}
}
swap(a[t],a[r]);
//用第r行消掉后面行的第c列
//这个乘法不好理解的话,考虑拆位
//如果元素值都是01,那么第i行需要操作仅当a[r][c],a[i][c]都是1
rep(i,r+1,n){
if(a[i][c]){
for(int j=n+1;j>=c;j--){
a[i][j]^=a[r][j]*a[i][c];
}
}
}
r++;
}
int tot=0;
rep1(i,n,1){
rep(j,i+1,n){
a[i][n+1]^=a[i][j]*a[j][n+1];
}
//0x=1无解
//1x=0只有x=0一个解,再这个例题里是不合法的
if(!a[i][i]&&a[i][n+1]||a[i][i]&&!a[i][n+1]){
cout<<"No";
return;
}
//0x=0有无穷个解,这里构造一组解,赋值为2**i
//保证自由元之间线性无关,互不影响
if(!a[i][i]){
a[i][n+1]=1ll<<tot;
tot++;
}
}
cout<<"Yes\n";
rep(i,1,n){
cout<<a[i][n+1]<<' ';
}
}
351

被折叠的 条评论
为什么被折叠?



