zoukankan      html  css  js  c++  java
  • bzoj3503 和谐矩阵

    Description

    我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本
    身,及他上下左右的4个元素(如果存在)。
    给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。

    Input

    输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。

    Output

    输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。

    设(x,y)为某个位置的取值(出界视为0),则有(x,y)^(x-1,y)^(x+1,y)^(x,y-1)^(x,y+1)=0

    即(x^y)=(x-1,y-1)^(x,y-1)^(x+1,y-1)^(x,y-2)

    由此确定矩阵第一行即确定了整个矩阵,若合法则矩阵第m+1行计算结果为全0 (不全0则第m行不合法)。

    设第一行为未知数,计算出第m+1行由第一行哪些位置的值异或得到,建立异或方程组,高斯消元求解即可。

    若一个元无法确定则定为1。

    时间复杂度O(n2m+n3),若数据规模更大则可以考虑压位。

    #include<cstdio>
    int n,m;
    int f[50][50][50];
    int xs[50][50],ys[50],as[50];
    int main(){
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++)f[1][i][i]=1,as[i]=1;
        for(int i=2;i<=m+1;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++)f[i][j][k]=f[i-1][j-1][k]^f[i-1][j][k]^f[i-1][j+1][k]^f[i-2][j][k];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)xs[i][j]=f[m+1][i][j];
        }
        int w=1;
        for(int i=1;i<=n;i++){
            for(int j=w;j<=n;j++){
                if(xs[j][i]){
                    for(int k=1;k<=n;k++){int a=xs[j][k];xs[j][k]=xs[w][k];xs[w][k]=a;}
                    int c=ys[j];ys[j]=ys[w];ys[w]=c;
                    break;
                }
            }
            if(!xs[w][i])continue;
            int yv=ys[w];
            for(int j=w+1;j<=n;j++){
                if(xs[j][i]){
                    ys[j]^=ys[w];
                    for(int k=1;k<=n;k++)xs[j][k]^=xs[w][k];
                }
            }
            w++;
        }
        for(int i=n;i>=1;i--){
            int mx=1;
            while(mx<=n&&!xs[i][mx])mx++;
            if(mx>n)continue;
            for(int j=mx+1;j<=n;j++){
                if(xs[i][j])xs[i][j]=0,ys[i]^=as[j];
            }
            as[mx]=ys[i];
        }
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                int v=0;
                for(int k=1;k<=n;k++)if(as[k]&&f[i][j][k])v^=1;
                printf("%d ",v);
            }
            putchar(10);
        }
        return 0;
    }
  • 相关阅读:
    作为前端开发兼任产品专员是一种咋样的体验
    css忽略某一层的存在:pointer-events:none
    响应式网站对百度友好关键
    移动站点对百度友好全解
    如何布局您的PC站和移动站,并表达两者之间内容的对应关系
    猫眼电影App抓包获取评论数据接口
    字符串模拟大数相加——Java实现
    计算机网络知识小结
    二叉树与双向链表问题
    算法编程题积累(4)——腾讯笔试"有趣的数字“问题
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5220298.html
Copyright © 2011-2022 走看看