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;
}
一个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;
}
相关文章推荐
- UVALive 5070 Awkward Lights 数学 高斯消元
- UVALive 5070 Awkward Lights
- UVA 1560 - Extended Lights Out(高斯消元)
- 【高斯消元】[HDU 3359][POJ3999][UVALive4741]Kind of a Blur
- UVALive 7455 Linear Ecosystem (高斯消元)
- UVALive 6449 IQ Test --高斯消元?
- UVALive 3490 Generator(AC自动机+dp+高斯消元)
- UVALive 6449 IQ Test --高斯消元?
- UVALive - 3490 Generator 【数学】【高斯消元】
- UVAlive 3490 AC自动机+(整数)高斯消元
- UVALive 6184 - One-Dimensional Cellular Automaton 高斯消元模板题 (2012 Tokyo)
- UVALive 3490 (LA 3940) || ZOJ 2619 Generator AC自动机(或KMP) + 整数高斯消元 + 数学期望
- UVALive 6495 Probability Paradox AC自动机+高斯消元
- uva 1560 - Extended Lights Out(枚举 | 高斯消元)
- UVaLive 3490 - Generator (AC自动机 期望DP 高斯消元)
- uva 1560 - Extended Lights Out(枚举 | 高斯消元)
- UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)
- UVALive 6185 高斯消元浮点型模版
- UVALive - 3490 Generator AC自动机+高斯消元