码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

时间:2018-03-09 16:14:50      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:which   printf   i+1   oid   highlight   []   左右   注意   queue   

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

题意:

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

分析:

考虑一种暴力,设n*m个未知数,列n*m个方程

高斯消元解方程,注意全零矩阵不合法

那我们如果发现有自由元就将它们置为1

 

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define p(x,y) ((x-1)*m+y)
int a[1700][1700];
int n,m;
int tx[]={-1,0,0,0,1};
int ty[]={0,-1,0,1,0};
int which[1700*1700],ins[1700*1700];
void build(){
    int i,j,k;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            for(k=0;k<5;k++){
                int dx=i+tx[k],dy=j+ty[k];
                if(dx>=1&&dx<=n&&dy>=1&&dy<=m){
                    a[p(i,j)][p(dx,dy)]=1;
                }
            }
        }
    }
}
void Guass(){
    int i=1,j=1,k,p;
    while(i<=n*m&&j<=n*m){
        for(k=i;k<=n*m;k++){
            if(a[k][j])break;
        }
        if(a[k][j]){
            if(k!=i){
                for(p=j;p<=n*m+1;p++){
                    swap(a[k][p],a[i][p]);
                }
            }
            for(k=i+1;k<=n*m;k++){
                if(a[k][j]){
                    for(p=j;p<=n*m+1;p++){
                        a[k][p]^=a[i][p];
                    }
                }
            }
            which[i]=j;
            ins[j]=i;
            i++;
        }
        j++;
    }
    if(i>n*m)return ;
    int id=i;
    for(k=1;k<=n*m;k++){
        if(!ins[k]){
            which[id]=k;
            ins[k]=id++;
        }
    }
    for(k=i;k<=n*m;k++){
        a[k][n*m+1]=1;
    }
    for(k=i-1;k;k--){
        for(p=which[k]+1;p<=n*m;p++){
            if(a[k][p]){
                a[k][n*m+1]^=a[ins[p]][n*m+1];
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    build();
    Guass();
    int i,j;
    for(i=1;i<=n;i++){
        int f=0;
        for(j=1;j<=m;j++){
            if(!f)f=
            printf("%d",a[ins[p(i,j)]][n*m+1]);
        else printf(" %d",a[ins[p(i,j)]][n*m+1]);
        }
        puts("");
    }
}

 

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

标签:which   printf   i+1   oid   highlight   []   左右   注意   queue   

原文地址:https://www.cnblogs.com/suika/p/8534226.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!