題解 外星千足蟲(線性基+高斯消元)
阿新 • • 發佈:2018-08-11
置疑 pac 想要 %d ++ ldb printf ins n+1
題解 luogu外星千足蟲(線性基+高斯消元)
題目
luogu題目傳送門
題解想法
- 首先需要知道這是個異或方程對吧
然後既然看到位運算,又有這麽多,就可以考慮線性基(做題技巧),那我們就丟進去
接下來看一看線性基,哇,性質美妙
它不就是Gauss消元裏面想要的上三角矩陣嗎所以說:
- 如果能拼成線性基,那麽枚舉到哪裏完成了,就輸出位置(first_ans)
- 如果拼不成,那就解不出(毋庸置疑)
- 那真是
美妙啊。。。所以怎麽消元呢?這可是個異或方程,我們要解出來啊
枚舉整個線性基的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!!!
題解 外星千足蟲(線性基+高斯消元)