高斯消元模版

加法高斯消元

这个很好理解,指一步步消掉未知数,然后回推,这里就不详细说了

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define ull /*unsigned*/ long long
#define fd(i,a,b) for(int i=a,_i=b;i<=_i;i=-~i)
#define bd(i,a,b) for(int i=a,_i=b;i>=_i;i=~-i)
#define Db(a,b,ans) cout<<a<<';'<<b<<','<<ans<<endl
#define debug puts("-----------");
using namespace std;

const int N=1e3+509,M=2e5+509,mod=998244353;
int n;
double mp[N][N];
double ans[N];
double o=0.00000001;

signed main()
{
//#ifdef FJ
	freopen("Gauss.in","r",stdin);
	freopen("Gauss.out","w",stdout);
//#endif
	cin>>n;
	fd(i,1,n)
	{
		fd(j,1,n+1)
		{
			cin>>mp[i][j];
		}
	}
	fd(i,1,n)
	{
		int r=i;
		fd(j,i+1,n)
		{
			if(fabs(mp[r][i]<fabs(mp[j][i]))) r=j;
		}
		if(fabs(mp[r][i])<o&&fabs(mp[n+1][i])>o)
		{
			cout<<"No Solution";
			return 0;
		}
		if(fabs(mp[r][i])<o&&fabs(mp[n+1][i])<o)
		{
			cout<<"Infinite group solutions";
			return 0;
		}
		if(i!=r) swap(mp[i],mp[r]);
		double d=mp[i][i];
		fd(j,i,n+1) mp[i][j]/=d;
		fd(j,i+1,n)
		{
			d=mp[j][i];
			fd(k,i,n+1) mp[j][k]-=mp[i][k]*d;
		}
	}
	ans[n]=mp[n][n+1];
	bd(i,n-1,1)
	{
		ans[i]=mp[i][n+1];
		fd(j,i+1,n) ans[i]-=(mp[i][j]*ans[j]);
	}
	fd(i,1,n) printf("%.2lf\n",ans[i]);
	return 0; 
}

高斯消元解异或线性方程组

异或运算有一个别名"不进位的加法",可以利用高斯消元的方法求解异或线性方程组

不过这里不用减法消去未知数而是用异或

注:最后有不用宏定义的版本

#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a,_i=b;i<=_i;i=-~i)
#define bd(i,a,b) for(int i=a,_i=b;i>=_i;i=~-i)
using namespace std;

const int N=110;
int n;
int a[N][N];

int Gause()
{
	int r=1;
	fd(c,1,n)
	{
		// 找非零行
		int t=r;
		fd(i,r,n)
		{
			if(a[i][c])
			{
				t=i;// 找到一个非零行即可
				break;
			}
		}
		if(!a[t][c]) continue;
		// 如果找到的这一行是0,则这一列不需要消元,看下一列
		fd(i,c,n+1) swap(a[t][i],a[r][i]);
		// 交换到未确定部分的顶行
		fd(i,r+1,n)
		{
			if(a[i][c])// 如果非0则需要消元
			{
				bd(j,n+1,c) a[i][j]^=a[r][j];
			}
		}
		// 当前行处理完毕,位置固定,处理下一行
		r++;
	}
	if(r<=n)
	{
		// 左边为0 右边不为0 无解
		fd(i,r,n) if(a[i][n+1]) return -1;
		// 无穷多解
		return 1;
	}
	bd(i,n,1)
	{
		fd(j,i+1,n)
		{
			a[i][n+1]^=a[i][j]*a[j][n+1];
			// 等价于 if (a[i][j]) a[i][n+1] ^= a[j][n+1];
		}
	}
	return 0;
}

signed main()
{
#ifdef FJ
	freopen("switch.in","r",stdin);
	freopen("switch.out","w",stdout);
#endif
	cin>>n;
    fd(i,1,n)
        fd(j,1,n+1)
            cin>>a[i][j];
    int t=Gause();
    if(t==0) fd(i,1,n) cout<<a[i][n+1]<<endl;
    else if(t==1) puts("Multiple sets of solutions");
    else puts("No solution");
	return 0;
}

\(None\ Define:\)

#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a,_i=b;i<=_i;i=-~i)
#define bd(i,a,b) for(int i=a,_i=b;i>=_i;i=~-i)
using namespace std;

const int N=110;
int n;
int a[N][N];

int Gause()
{
	int r=1;
	for(int c=1;c<=n;c=-~c)
	{
		// 找非零行
		int t=r;
		for(int i=r;i<=n;i=-~i)
		{
			if(a[i][c])
			{
				t=i;// 找到一个非零行即可
				break;
			}
		}
		if(!a[t][c]) continue;
		// 如果找到的这一行是0,则这一列不需要消元,看下一列
		for(int i=c;i<=n+1;i=-~i) swap(a[t][i],a[r][i]);
		// 交换到未确定部分的顶行
		for(int i=r+1;i<=n;i=-~i) 
		{
			if(a[i][c])// 如果非0则需要消元
			{
				for(int j=n+1;j>=c;j=~-j) a[i][j]^=a[r][j];
			}
		}
		// 当前行处理完毕,位置固定,处理下一行
		r++;
	}
	if(r<=n)
	{
		// 左边为0 右边不为0 无解
		for(int i=r;i<=n;i=-~i) if(a[i][n+1]) return -1;
		// 无穷多解
		return 1;
	}
	for(int i=n;i>=1;i=~-i)
	{
		for(int j=i+1;j<=n;j=-~j)
		{
			a[i][n+1]^=a[i][j]*a[j][n+1];
			// 等价于 if (a[i][j]) a[i][n+1] ^= a[j][n+1];
		}
	}
	return 0;
}

signed main()
{
#ifdef FJ
	freopen("switch.in","r",stdin);
	freopen("switch.out","w",stdout);
#endif
	cin>>n;
    for(int i=1;i<=n;i=-~i)
        for(int j=1;j<=n+1;j=-~j)
            cin>>a[i][j];
    int t=Gause();
    if(t==0) for(int i=1;i<=n;i=-~i) cout<<a[i][n+1]<<endl;
    else if(t==1) puts("Multiple sets of solutions");
    else puts("No solution");
	return 0;
}
posted @ 2024-07-05 17:13  whrwlx  阅读(4)  评论(0编辑  收藏  举报