高斯消元

这是什么“玩意”

Posted by JU on July 17, 2018

Luogu2455(普通方程)

#include <bits/stdc++.h>
#define pr(p) printf("%d\n",p)
const int oo=2139063143;
const int N=210;
const int mod=1000000007;
using namespace std;
typedef long long LL;
typedef double db;
const db eps=1e-8;
inline void sc (int &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
db ans[N],a[N][N];
int n,m;
int gauss ()//-1:No Solution  0:Infinity Roots
{
    if (m< n) return 0;
    int an=1;
    for (int i=1; i<=n; i++)
    {
        int k=i;
        for (int j=i+1; j<=m; j++)
            if (abs (a[k][i])< abs (a[j][i]))
                k=j;
        for (int j=1; j<=n+1; j++)
            swap (a[i][j],a[k][j]);
        if (abs (a[i][i])< eps) continue;
        for (int j=1; j<=m; j++) if (j!=i)
        {
            db p=a[j][i]/a[i][i];
            for (int k=1; k<=n+1; k++)
                a[j][k]-=a[i][k]*p;
        }
    }
    int s1=0,s2=0;
    for(int i=1; i<=n; i++)
    {
        int sb=0;
        for (int j=1; j<=n+1; j++)
            if(abs (a[i][j])< eps) ++sb;
        if (sb==n&&abs (a[i][n+1])> eps)
            s2=1;
        if (sb==n+1)
            s1=1;
    }
    if (s2) return -1;
    if (s1) return 0;
    for (int i=n+1; i<=m; i++)
        if (abs (a[i][n+1])> eps) return -1;
    for (int i=1; i<=n; i++)
    {
        ans[i]=a[i][n+1]/a[i][i];
        if (abs (ans[i])< eps) ans[i]=0;
    }
    return an;
}
int main()
{
    //freopen (".in","r",stdin);
    //freopen (".out","w",stdout);
    sc(n); m=n;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=n+1; j++)
            scanf ("%lf",&a[i][j]);
    int sb=gauss ();
    if (sb< 1) pr(sb);
    else
        for (int i=1; i<=n; i++)
            printf ("x%d=%.2lf\n",i,ans[i]);
    return 0;
}

Luogu2447(异或方程bitset优化)

#include <bits/stdc++.h>
#define pr(p) printf("%d\n",p)
const int oo=2139063143;
const int N=1010;
const int mod=1000000007;
using namespace std;
typedef long long LL;
inline void sc (int &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
int n,m;
bitset <N> a[N<<1];
int ans[N];
bool gauss ()
{
    if (m< n) return 0;
    ans[0]=n;
    for (int i=1; i<=n; i++)
    {
        int k=i;
        if (!a[i][i])
            for (int j=i; j<=m; j++)
                if (a[j][i]) { ans[0]=max (j,ans[0]); k=j; break; }
        if (k!=i) swap (a[k],a[i]);
        if (!a[i][i]) return 0;
        for (int j=1; j<=m; j++) if (j!=i&&a[j][i])
            a[j]^=a[i];
    }
    for (int i=1; i<=n; i++)
        ans[i]=a[i][n+1];
    return 1;
}
char sb[N];
int main()
{
    //freopen (".in","r",stdin);
    //freopen (".out","w",stdout);
    sc(n),sc(m);
    for (int i=1; i<=m; i++)
    {
        scanf ("%s",sb+1);
        for (int j=1; j<=n; j++)
            a[i][j]=sb[j]-'0';
        int ss; sc(ss);
        a[i][n+1]=ss;
    }
    bool ass=gauss ();
    if (!ass) { puts("Cannot Determine"); return 0; }
    pr(ans[0]);
    for (int i=1; i<=n; i++)
        puts(ans[i]?"?y7M#":"Earth");
    return 0;
}

Luogu3164(异或方程)

#include <bits/stdc++.h>
#define pr(p) printf("%d\n",p)
const int oo=2139063143;
const int N=45;
const int mod=1000000007;
using namespace std;
typedef long long LL;
inline void sc (int &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
int n,m;
int ans[N][N];
int a[N][N],f[N][N][N];
void gauss ()
{

    for (int i=1; i<=m; i++)
    {
        int k=i;
        for (int j=i; j<=m; j++)
            if (a[j][i]) { k=j; break; }
        for (int j=1; j<=m+1; j++)
            swap (a[i][j],a[k][j]);
        if (!a[i][i]) continue;
        for (int j=i+1; j<=m; j++) if (a[j][i])
            for (int k=1; k<=m+1; k++)
                a[j][k]^=a[i][k];
    }
    for (int i=m; i> 0; i--)
    {
        ans[1][i]=0;
        for (int j=m; j> i; j--)
            if (a[i][j]) ans[1][i]^=ans[1][j];
        if (!a[i][i]) ans[1][i]=1;
    }
}
int main()
{
    //freopen (".in","r",stdin);
    //freopen (".out","w",stdout);
    sc(n),sc(m);
    for (int j=1; j<=m; j++)
        f[1][j][j]=1;
    for (int i=2; i<=n; i++)
        for (int j=1; j<=m; j++)
        {
            for (int k=1; k<=m; k++)
                f[i][j][k]=f[i-1][j-1][k]^f[i-1][j][k]^f[i-1][j+1][k]^f[i-2][j][k];
        }
    for (int j=1; j<=m; j++)
        for (int k=1; k<=m; k++)
            a[j][k]=f[n][j-1][k]^f[n][j][k]^f[n][j+1][k]^f[n-1][j][k];
    gauss ();
    for (int i=2; i<=n; i++)
        for (int j=1; j<=m; j++)
            ans[i][j]=ans[i-1][j-1]^ans[i-1][j]^ans[i-1][j+1]^ans[i-2][j];
    for (int i=1; i<=n; i++,putchar('\n'))
        for (int j=1; j<=m; j++)
            printf ("%d ",ans[i][j]);
    return 0;
}

POJ2947(同余方程)

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int mod=7;
int n,m;
int a[300+10][300+10];
char c1[10],c2[10],c[10][10]={"1","MON","TUE","WED","THU","FRI","SAT","SUN"};//星期几
int get(char p[]) { for (int i=1;i<=7;i++) if(!strcmp(p,c[i])) return i; }
int gauss()
{
    int i,j;
    for (i=1,j=1;i<=m&&j<=n;j++)
    {
        int k=i;
        while(k<=m&&!a[k][j]) k++;//找一个1...j前序数全为零的方程
        if(a[k][j])
        {
            for (int p=1;p<=n+1;p++) swap(a[k][p],a[i][p]);//把k行序数与i行交换保证了阶梯矩阵
            for (int h=1;h<=m;h++) if (h!=i)
            {
                if(a[h][j])
                {
                    int x=a[i][j],y=a[h][j];
                    for (int p=1;p<=n+1;p++) a[h][p]=((a[h][p]*x-a[i][p]*y)%mod+mod)%mod;
                }
            }
            i++;
        }
    }
    for (int p=i;p<=m;p++) if(a[p][n+1]) return -1;
    if(i<=n) return n-i+1;

    for (int x=n;x>=1;x--)
    {
        while(a[x][n+1]%a[x][x]!=0) a[x][n+1]+=7;
        a[x][n+1]=(a[x][n+1]/a[x][x])%mod;
    }

    return 0;
}
int main()
{
    while(scanf("%d%d",&n,&m)&&n)
    {
        int k,v;
        memset(a,0,sizeof(a));
        for (int i=1;i<=m;i++)
        {
            scanf("%d%s%s",&k,c1,c2);
            a[i][n+1]=(get(c2)-get(c1)+8)%mod;
            for (int j=1;j<=k;j++) { scanf("%d",&v); a[i][v]++; }
            for (int j=1;j<=n;j++) a[i][j]%=7;
        }
        int t=gauss();
        if(t==-1) printf("Inconsistent data.\n");
        else if(t) printf("Multiple solutions.\n");
        else
        {
            for (int i=1;i<=n;i++)
                if(a[i][n+1]<3) a[i][n+1]+=mod;
            for (int i=1;i<n;i++) printf("%d ",a[i][n+1]);
            printf("%d\n",a[n][n+1]);
        }
    }
    return 0;
}

行列式

线性基

CC 原创文章采用CC BY-NC-SA 4.0协议进行许可,转载请注明:“转载自:高斯消元