【高斯消元】BZOJ3503 [Cqoi2014]和谐矩阵
3503: [Cqoi2014]和谐矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1197 Solved: 570
[Submit][Status][Discuss]
Description
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本
身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
Input
输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。
Output
输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。
Sample Input
4 4
Sample Output
0 1 0 0
1 1 1 0
0 0 0 1
1 1 0 1
数据范围
1 <=m, n <=40
1 1 1 0
0 0 0 1
1 1 0 1
数据范围
1 <=m, n <=40
题解
高斯消元解异或方程组
将第一行的未知数设成xi
则可以推出其他行和xi的关系
解方程组即可
代码
//by 减维 #include<set> #include<map> #include<queue> #include<ctime> #include<cmath> #include<bitset> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define il inline #define rg register #define db double #define mpr make_pair #define maxn 2005 #define inf (1<<30) #define eps 1e-8 #define pi 3.1415926535897932384626L using namespace std; inline int read() { int ret=0;bool fla=0;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-'){fla=1;ch=getchar();} while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();} return fla?-ret:ret; } int n,m,cnt,pos[maxn]; int tx[4]={1,0,0,-1}; int ty[4]={0,1,-1,0}; bitset<maxn> a[maxn]; il int gi(int x,int y){return (x-1)*m+y;} void gauss() { int now=0; for(int i=1;i<=n*m;++i) { int j=now+1; while(!a[j][i]&&j<=n*m) j++; now++; swap(a[j],a[now]); for(int k=1;k<=n*m;++k) if(a[k][i]&&k!=now) a[k]^=a[now]; } } int main() { n=read(),m=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { a[gi(i,j)][gi(i,j)]=1;cnt=1; for(int k=0;k<4;++k) { int x=i+tx[k],y=j+ty[k]; if(x<=0||y<=0||x>n||y>m) continue ; a[gi(i,j)][gi(x,y)]=1;cnt++; } a[gi(i,j)][n*m+1]=(cnt&1); } gauss(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) printf("%d%c",a[gi(i,j)][n*m+1]==0?1:0,j==m?'\n':' '); return 0; }
补充:实数域的高斯消元
//by 减维 #include<set> #include<map> #include<queue> #include<ctime> #include<cmath> #include<bitset> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define il inline #define rg register #define db double #define mpr make_pair #define maxn 505 #define inf (1<<30) #define eps 1e-5 #define pi 3.1415926535897932384626L using namespace std; inline int read() { int ret=0;bool fla=0;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-'){fla=1;ch=getchar();} while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();} return fla?-ret:ret; } int n,m,du[maxn],ed[maxn*maxn/2][2]; db ans,a[maxn][maxn],v[maxn],val[maxn*maxn/2]; bool cmp(db x,db y){return x>y;} void gauss() { for(int i=1;i<=n;++i) { int j=i; for(int k=i+1;k<=n;++k) if(fabs(a[k][i])>fabs(a[j][i])) j=k; if(i!=j) for(int k=i;k<=n+1;++k) swap(a[i][k],a[j][k]); for(int k=i+1;k<=n;++k) { db p=a[k][i]/a[i][i]; for(int t=i;t<=n+1;++t) a[k][t]-=a[i][t]*p; } } for(int i=n;i;i--) { for(int j=i+1;j<=n;++j) a[i][n+1]-=a[i][j]*v[j]; v[i]=a[i][n+1]/a[i][i]; } } int main() { n=read(),m=read(); for(int i=1;i<=m;++i) { ed[i][0]=read(),ed[i][1]=read(); du[ed[i][0]]++;du[ed[i][1]]++; } for(int i=1;i<=m;++i) { a[ed[i][0]][ed[i][1]]=1.0/du[ed[i][1]]; a[ed[i][1]][ed[i][0]]=1.0/du[ed[i][0]]; } for(int i=1;i<n;++i) a[i][i]=-1.0; for(int i=1;i<=n;++i) a[n][i]=0; a[n][n]=1;a[1][n+1]=-1.0; gauss(); for(int i=1;i<=m;++i) val[i]=v[ed[i][0]]/du[ed[i][0]]+v[ed[i][1]]/du[ed[i][1]]; sort(val+1,val+m+1,cmp); for(int i=1;i<=m;++i) ans+=1.0*val[i]*i; printf("%.3lf",ans); return 0; }