题目大意:
给你一个n*m的矩阵,只会出现0或1,然你求出每个点和左右上下的点的异或和为1。
思路:
这题拿到一点想法都没有,高斯消元我可能学过也可能没学过吧,反正什么感觉都没有,然后就直接gg,作为比赛的第一题我一分都没有…..
其实还是很好写的,因为这是mu版题。只要把高斯消元里面的加减乘除都换成异或运算就好了
程序:
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define p 45
#define maxn 1800
using namespace std;
const int dx[]={0,0,0,1,-1};
const int dy[]={0,1,-1,0,0};
int n,m;
int x[maxn],crs[maxn],a[maxn][maxn],id[p][p],cnt;
void Gauss(int n,int m){
int i,j,k,id;
for(id=i=1;i<=m;i++,id++)
{
for(j=id;j<=n&&!a[j][i];j++);
if(j>n){id--;continue;}
else crs[id]=i;
if(id!=j)for(k=i;k<=m;k++)swap(a[id][k],a[j][k]);
for(j=id+1;j<=n;j++)if(a[j][i])for(k=i;k<=m;k++)
a[j][k]^=a[id][k];
}id--;
for(i=m;i;i--)
{
if(i!=crs[id]){x[i]=1;continue;}
int ret=a[id][n];
for(j=m;j>i;j--)if(a[id][j])ret^=x[j];
x[i]=ret;
id--;
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
id[i][j]=++cnt;
int tx,ty;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
for (int k=0;k<=4;k++)
if (id[tx=i+dx[k]][ty=j+dy[k]]) a[id[i][j]][id[tx][ty]]=1;
Gauss(cnt+1,cnt);
cnt=0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
printf("%d ",x[++cnt]);
printf("\n");
}
}