#include<cstdio>
#include<cstring>
#include<ctime>
#include<map>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=300;
const int inf=0x3f3f3f3f;
int equ,var;//equ是方程数也就是行数,var是变元也就是列数
int a[maxn][maxn];//增广矩阵
int x[maxn];//解集
int free_x[maxn];//自由变元(多解枚举自由变元可以使用)
int free_num;//自由变元的个数
//返回值为-1代表无解,0为唯一解,否则返回自由变元的个数
int Gauss()
{
int max_r,col,k;
free_num=0;
for(k=0,col=0; k<equ&&col<var; k++,col++)
{
//col代表正在处理的这一列
max_r=k;//表示当前列中元素绝对值最大的行
for(int i=k+1; i<equ; i++)
{
if(abs(a[i][col])>abs(a[max_r][col]))
max_r=i;
}
if(max_r!=k)//与第k行交换
{
for(int j=col; j<var+1; j++)
swap(a[k][j],a[max_r][j]);
}
if(a[k][col]==0)//说明该col列第k行一下全是0,处理当前行的下一列
{
k--;
free_x[free_num++]=col;
continue;
}
for(int i=k+1; i<equ; i++) //枚举要删除的行
{
if(a[i][col]!=0)
{
// int LCM=lcm(abs(a[i][col],abs(a[k][col])));
// int ta=LCM/abs(a[i][col]);
// int tb=LCM/abs(a[k][col]);
// if(a[i][col]*a[k][col]<0)
// tb=-tb;
// for(int j=col;j<var+1;j++)
// {
// a[i][j]=a[i][j]*ta-a[k][j]*tb;
// }
for(int j=col; j<var+1; j++)
{
a[i][j]^=a[k][j];
}
}
}
}
for(int i=k; i<equ; i++)
if(a[i][col]!=0)
return -1;//无解
if(k<var)//有多解
{
int star=1<<(var-k);//枚举变元
int res=inf;
for(int i=0;i<star;i++)
{
int cnt=0;
int tmp=i;
for(int j=0;j<var-k;j++)//得到每一个变元的值
{
x[free_x[j]]=(tmp&1);
cnt+=x[free_x[j]];
tmp>>=1;
}
for(int j=k-1;j>=0;j--)//回代
{
int tmp=a[j][var];
for(int l=j+1;l<var;l++)
tmp^=(a[j][l]&&x[l]);
x[j]=tmp;
cnt+=x[j];
}
res=min(res,cnt);//选取最小值
}
return res;
}
//唯一解 ,回代
for(int i=var-1; i>=0; i--)
{
x[i]=a[i][var];
for(int j=i+1; j<var; j++)
x[i]^=(a[i][j]&&x[j]);
}
return 0;
}
void init(int n)
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
memset(free_x,1,sizeof(free_x));
equ=n*n;
var=n*n;
for(int i=0; i<n; i++)//建立方程组
for(int j=0; j<n; j++)
{
int t=i*n+j;
a[t][t]=1;//自己的变元肯定对自己有影响
if(i>0) a[(i-1)*n+j][t]=1;
if(j>0) a[t-1][t]=1;
if(i<n-1) a[(i+1)*n+j][t]=1;
if(j<n-1) a[t+1][t]=1;
}
}
int main()
{
int ncase,Z=0;
scanf("%d",&ncase);
while(ncase--)
{
int n;
scanf("%d",&n);
init(n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
char c;
scanf(" %c",&c);
if(c=='w')
a[i*n+j][n*n]=1;
else a[i*n+j][n*n]=0;
}
}
int tmp=Gauss();
if(tmp==-1)
printf("inf\n");
else
printf("%d\n",tmp);
}
}
高斯消元
高斯消元法求解线性方程组
最新推荐文章于 2025-09-23 08:35:00 发布
本文介绍了一个使用高斯消元法求解线性方程组的C++程序实现。该程序能够处理方程组并判断其是否有解、唯一解或多解的情况,并能求出解或最小化解的数量。适用于解决诸如网格中黑白格子最少数量等实际问题。
622

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



