1. 程式人生 > >題解 外星千足蟲(線性基+高斯消元)

題解 外星千足蟲(線性基+高斯消元)

置疑 pac 想要 %d ++ ldb printf ins n+1

題解 luogu外星千足蟲(線性基+高斯消元)

題目

luogu題目傳送門

題解想法

  1. 首先需要知道這是個異或方程對吧
    然後既然看到位運算,又有這麽多,就可以考慮線性基(做題技巧),那我們就丟進去
    接下來看一看線性基,哇,性質美妙
    它不就是Gauss消元裏面想要的上三角矩陣嗎
  2. 所以說:

    • 如果能拼成線性基,那麽枚舉到哪裏完成了,就輸出位置(first_ans)
    • 如果拼不成,那就解不出(毋庸置疑)
  3. 那真是美妙啊。。。
  4. 所以怎麽消元呢?這可是個異或方程,我們要解出來啊
    枚舉整個線性基的g[i]
    如果g[i][j]這一位上為1,是不是就有一個未知數!
    (註意這是個異或方程)
    我們的線性基在g[j][j]上是一定會有數的對吧

    那我們直接給g[i]異或一下g[j]不就消掉了!!!
    直到枚舉玩整個g[i],剩下的y(輸入的那個"等號右邊"的)如果為0就是地球了,為1就是外星了(單數只腳。。。)

code

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#define lst long long
#define ldb long double
#define N 2050
using namespace std;
const int Inf=1e9;
int read()
{
    int s=0,m=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
    while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return m?-s:s;
}

int m,n,Done;
bitset<N>f[N],g[N];

void Insert(int now)//線性基插入
{
    for(int j=1;j<=n;++j)
    {
        if(f[now][j])
        {
            if(!g[j][j]){g[j]=f[now],Done++;break;}
            f[now]^=g[j];
        }
    }
}

void Gauss()//高斯消元
{
    for(int i=1;i<=n;++i)
    {
        for(int j=i+1;j<=n;++j)
            if(g[i][j])g[i]^=g[j];

        if(g[i][n+1])puts("?y7M#");
        else puts("Earth");
    }
}

int main()
{
    n=read(),m=read();
    char x;int y;
    for(int i=1;i<=m;++i)
    {
        for(int j=1;j<=n;++j)
            cin>>x,y=x-'0',f[i][j]=y;
        cin>>x,y=x-'0',f[i][n+1]=y;
    }
    for(int i=1;i<=m;++i)
    {
        Insert(i);
        if(Done==n){printf("%d\n",i);break;}
    }
    if(Done!=n){puts("Cannot Determine");return 0;}

    Gauss();

    return 0;
}

yeh!!!

題解 外星千足蟲(線性基+高斯消元)