您的位置:首页 > 其它

Awkward Lights [UVALive 5070] 高斯消元

2011-04-08 19:40 357 查看
题意:

一个0/1矩阵,表示开关,0关,1开,按(i,j)这个开关后则跟他曼哈顿距离为d的开关改变状态.

问能否将改状态变为全0.

题解:

首先逆向思维,题目要求等价于将全0变为所求矩阵.

然后对于每一个开关,要么按一次,要么不按,按两次以上等价于按了%2次,设未知数x(i,j)表示按1次或0次.

则可以列n*m个方程:

x(i,j)+sigma(x(ii,jj))=a[i][j] (a[i][j]为给定0/1矩阵里的值,x(ii,jj)跟(i,j)曼哈顿距离为d的开关)

代码:



/*

* File: main.cpp

* Author: swordholy

*

* Created on 2011年4月6日, 下午1:10

*/



#include <cstdlib>

#include <stdio.h>

#include <iostream>

#include <stdio.h>

#include <memory.h>

using namespace std;

#define MAXN 650

struct Matrix

{

int n,m;

int e[MAXN][MAXN];

void set(int mm)

{

n=0;m=mm;

memset(e,0,sizeof(e));

}

void AddEq(int *a)

{

n++;

int i;

for(i=1;i<=m;i++)

e
[i]=a[i];

}

void swap(int u,int v)

{

int i,temp;

for(i=1;i<=m;i++)

{

temp=e[u][i];

e[u][i]=e[v][i];

e[v][i]=temp;

}

}

bool gauss()

{

int i,j,k,maxk,kk;

for(i=1,j=1;i<=n&&j<=m-1;i++,j++)

{

maxk=i;

for(k=i+1;k<=n;k++)

if (e[i][j]<e[k][j]) maxk=k;

swap(i,maxk);

if (e[i][j]==0) {i--;continue;}

for(k=i+1;k<=n;k++)

{

if (e[k][j]==0) continue;

for(kk=1;kk<=m;kk++)

e[k][kk]^=e[i][kk];

}

}

for(k=i;k<=n;k++)

if (e[k][m]!=0) return 0;

return 1;

}



};

Matrix mt;

int a[MAXN][MAXN];

int n,m;

int idx(int i,int j)

{

return (i-1)*m+j;

}

int t[MAXN];

int main(int argc, char** argv)

{

int i,j,k,d;

while(scanf("%d%d%d",&m,&n,&d)!=EOF)

{

if ( (n==0)&&(m==0)&&(d==0) ) break;

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

scanf("%d",&a[i][j]);

mt.set(n*m+1);

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

{

memset(t,0,sizeof(t));

t[idx(i,j)]=1;

for(int ii=1;ii<=n;ii++)

for(int jj=1;jj<=m;jj++)

if (abs(i-ii)+abs(j-jj)==d)

{

t[idx(ii,jj)]=1;

}

t[n*m+1]=a[i][j];

mt.AddEq(t);

}

printf("%d/n",mt.gauss());

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: