【高斯消元】BZOJ3503 [Cqoi2014]和谐矩阵

3503: [Cqoi2014]和谐矩阵

Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge
Submit: 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

题解

高斯消元解异或方程组

将第一行的未知数设成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;
}

 

posted @ 2018-03-16 14:44  减维  阅读(218)  评论(0编辑  收藏  举报