高斯消元解Xor方程组
Orz ZYF o(︶︿︶)o 唉我的数学太烂了……
错误思路:对每个格点进行标号,然后根据某5个异或和为0列方程组,高斯消元找自由元……(目测N^3会TLE)
ZYF的正确思路:
如果第一行的数知道了,我们就可以推出其他行的数。
那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意。
那么,我们就有了一种想法。
直接把m+1行的每个数用x[1..n]表示出来,这一定是个系数只为0/1的式子。然后让这个异或值=0,就可以解异或方程组了。
有个奇怪错误:将long long 直接转成bitset会有位数丢了……只能一位一位往过转= =
1 /************************************************************** 2 Problem: 3503 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:56 ms 7 Memory:1292 kb 8 ****************************************************************/ 9 10 //BZOJ 3503 11 #include<bitset> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 using namespace std; 21 int getint(){ 22 int v=0,sign=1; char ch=getchar(); 23 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 24 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 25 return v*=sign; 26 } 27 /******************tamplate*********************/ 28 const int N=55; 29 int n,m; 30 typedef long long LL; 31 LL b[N][N]; 32 bitset<N>a[N],c[N]; 33 34 void gauss(){//准确的说这是高斯-约当消元法? 35 F(i,1,n+1){ 36 int j=i; 37 while(j<=n && !a[j][i]) j++; 38 if(j>n) continue;//如果这一位全是0……(自由元) 39 if(i!=j) swap(a[i],a[j]); 40 F(j,1,n) 41 if(i!=j && a[j][i]) a[j]^=a[i]; 42 } 43 } 44 int main(){ 45 ios::sync_with_stdio(false); 46 m=getint(); n=getint(); 47 48 F(i,1,n) b[1][i]=(LL)1<<i-1; 49 50 F(i,2,m+1) 51 F(j,1,n) 52 b[i][j]=b[i-1][j]^b[i-1][j-1]^b[i-1][j+1]^b[i-2][j]; 53 F(i,1,n) 54 F(j,1,n) 55 a[i][j]=b[m+1][i]>>(j-1)&1; 56 // a[i]=b[m+1][i],a[i]<<=1; 这里不能这样直接转bitset,否则会出错sad 57 58 //b[m+1][i]的意义是: 59 //若使b[m+1][i]为0,则第一行的哪几个异或起来和为0 60 gauss(); 61 D(i,n,1){ 62 c[1][i]=a[i][n+1]; 63 if(!a[i][i]){c[1][i]=1; continue;}//令自由元为1(以保证矩阵不全为0) 64 F(j,i+1,n) if (a[i][j]) c[1][i]=c[1][i]^c[1][j]; 65 }//解出第一行的0/1情况 66 F(i,2,m) 67 F(j,1,n) 68 c[i][j]=c[i-1][j]^c[i-1][j-1]^c[i-1][j+1]^c[i-2][j]; 69 F(i,1,m){ 70 F(j,1,n-1) cout <<c[i][j]<<" "; 71 cout <<c[i][n]<<endl; 72 } 73 return 0; 74 }
3503: [Cqoi2014]和谐矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 484 Solved: 212
[Submit][Status][Discuss]
Description
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本
身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
Input
输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。
Output
输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。
Sample Input
4 4
Sample Output
0100
1110
0001
1101
数据范围
1 <=m, n <=40
1110
0001
1101
数据范围
1 <=m, n <=40