高斯消元模板:
#include<bits/stdc++.h>
#define N 105
using namespace std;
double a[N][N]; int n;
bool gauss(){
for(int i=1;i<=n;i++){
int k=i;
for(int j=i+1;j<=n;j++)
if(fabs(a[j][i])>fabs(a[k][i])) k=j;
if(fabs(a[k][i])<1e-8) return 0;//最大的都小于10^-8
for(int j=i;j<=n+1;j++) swap(a[i][j],a[k][j]);
double res=a[i][i];
for(int j=i;j<=n+1;j++) a[i][j]/=res;
for(int k=1;k<=n;k++)
if(k!=i){
double res=a[k][i];
for(int j=i;j<=n+1;j++) a[k][j]-=res*a[i][j];
}
}
return 1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)
cin>>a[i][j];
if(gauss())
for(int i=1;i<=n;i++)
printf("%0.2lf\n",a[i][n+1]);
else cout<<"No Solution";
return 0;
}
EXTENDED LIGHTS OUT
题意:给出一个全是01构成的,翻一个点会影响上下左右,问你怎么操作后可以得到全为0
状压dp可以做
不够我们这次用高斯校园
我们可以
M[0][0]x[0]^M[0][1]x[1]^…^M[0][N-1]x[N-1]=B[0]//B[0]是目前第一个鸽子的状态
M[1][0]x[0]^M[1][1]x[1]^…^M[1][N-1]x[N-1]=B[1]
因为我们知道一个状态和他被操做次数奇偶有关,所以直接异或,我们直接改动高斯消元模板的加号为^就行。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[5][6];
int g[35][35],res[35];
int n;
int Gauss(){
int pos;
for(int k=0;k<n;k++){
pos=-1;
for(int i=k;i<n;i++) //找到这一列中第一个非0元素的行
if(g[i][k]!=0){
pos=i;
break;
}
for(int i=k;i<=n;i++)
swap(g[k][i],g[pos][i]); //交换位置,我们在学线性代数的时候也经常这么做
for(int i=k+1;i<n;i++){
if(g[i][k]==0)
continue;
for(int j=k;j<=n;j++) //对于下面出现的这一列中有1的行,需要把1消掉
g[i][j]^=g[k][j];
}
}
for(int i=n-1;i>=0;i--){
for(int j=0;j<i;j++){
if(g[j][i]==0)
continue;
for(int k=0;k<=n;k++)
g[j][k]^=g[i][k];
}
int flag=0;
for(int j=0;j<n;j++)
if(g[i][j]){
flag=1;
break;
}
if(!flag) //如果某一行的系数全是0,说明就不对了
return 0;
res[i]=g[i][n];
}
return 1;
}
int main(){
//freopen("input.txt","r",stdin);
int t,cases=0;
scanf("%d",&t);
n=30;
while(t--){
memset(g,0,sizeof(g));
for(int i=0;i<5;i++)
for(int j=0;j<6;j++){
scanf("%d",&map[i][j]);
if(map[i][j])
g[6*i+j][n]=1;
}
for(int i=0;i<5;i++)
for(int j=0;j<6;j++){
g[i*6+j][i*6+j]=1;
if(i>0) g[6*i+j][6*(i-1)+j]=1;
if(j>0) g[6*i+j][6*i+j-1]=1;
if(i<4) g[6*i+j][6*(i+1)+j]=1;
if(j<5) g[6*i+j][6*i+j+1]=1;
}
printf("PUZZLE #%d\n",++cases);
Gauss();
for(int i=0;i<5;i++)
for(int j=0;j<6;j++)
printf("%d%c",res[i*6+j],j==5?‘\n‘:‘ ‘);
}
return 0;
}
原文:https://www.cnblogs.com/hgangang/p/11537624.html