【高斯消元】

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 <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=35;
typedef int mtx[N][N];
mtx a;
void gauss(mtx A, int n) {
for1(i, 1, n) {
int now=i;
while(!A[now][i] && now<=n) ++now;
for1(j, 1, n+1) swap(A[now][j], A[i][j]);
for1(j, i+1, n) if(A[j][i])
for1(k, i, n+1) A[j][k]^=A[i][k];
}
for3(i, n, 1)
for1(j, i+1, n) if(A[i][j]) A[i][n+1]^=A[j][n+1];
}
int main() {
int cs=getint();
for1(ttt, 1, cs) {
CC(a, 0);
for1(i, 1, 30) {
read(a[i][31]);
a[i][i]=1;
if(i%6!=1) a[i][i-1]=1; ·
if(i%6!=0) a[i][i+1]=1;
if(i>6) a[i][i-6]=1;
if(i<25) a[i][i+6]=1;
}
gauss(a, 30);
printf("PUZZLE #%d\n", ttt);
for1(i, 1, 30) {
printf("%d ", a[i][31]); if(i%6==0) puts("");
}
}
return 0;
}

高斯消元模板:


#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;

}

猜你喜欢

转载自www.cnblogs.com/hgangang/p/11537624.html