您的位置:首页 > 其它

poj1222高斯消元基础题

2012-09-01 10:08 274 查看
题意:一个5*6的矩阵,每个点只有0、 1两个状态,如果一个点的状态改变,则它周围的状态都会改变。问需要怎么按灯使得灯全灭。

以每个灯列一个方程,a[i*6+j][i*6+j]以及上下左右四个点均为1,其他点系数为0,等于a[i][j]异或0.

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=300;
int a[maxn][maxn],x[maxn];
int var,equ;
bool free_x[maxn+1];
int free_num;
int abs1(int num)
{
if(num>0) return num;
else return -1*num;
}
void Debug(void)
{
int i, j;
for (i = 0; i < equ; i++)
{
for (j = 0; j < var + 1; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
int gcd(int a,int b)
{
int t;
while(b!=0)
{
t=b;
b=a%b;
a=t;
}
return a;
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
void swap(int &a,int &b)
{
int tmp=a;a=b;b=tmp;
}
int Gauss_new()
{
int k,col=0;
for(k=0;k<equ&&col<var;++k,++col)
{
int max_r=k;
for(int i=k+1;i<equ;i++)
if(a[i][col]>a[max_r][col])
max_r=i;
if(max_r!=k)
{
for(int i=k;i<var+1;i++)
swap(a[k][i],a[max_r][i]);
}
if(a[k][col]==0)
{
k--;continue;
}
for(int i=k+1;i<equ;i++)
{
if(a[i][col]!=0)
{
int LCM=lcm(a[i][col],a[k][col]);
int ta=LCM/a[i][col],tb=LCM/a[k][col];
if(a[i][col]*a[k][col]<0)
ta=-tb;
for(int j=col;j<var+1;j++)
a[i][j]=((a[i][j]*ta)%2-(a[k][j]*tb)%2+2)%2;
}
}
}
for(int i=k;i<equ;i++)
if(a[i][col]!=0) return -1;
for(int i=k-1;i>=0;i--)
{
int tmp=a[i][var]%2;
for(int j=i+1;j<var;j++)
if(a[i][j]!=0)
tmp=(tmp-(a[i][j]*x[j])%2+2)%2;
x[i]=(tmp/a[i][i])%2;
}
return 0;
}
int main()
{
int t,cas=0,i,j,k;
scanf("%d",&t);
var=30,equ=30;
while(t--)
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
for(i=0;i<5;i++)
{
for(j=0;j<6;j++)
{
if(i-1>=0) a[i*6+j][(i-1)*6+j]=1;
if(i+1<=4) a[i*6+j][(i+1)*6+j]=1;
if(j-1>=0) a[i*6+j][i*6+j-1]=1;
if(j+1<=5) a[i*6+j][i*6+j+1]=1;
a[i*6+j][i*6+j]=1;
scanf("%d",&a[i*6+j][30]);
}
}
//Debug();
free_num=Gauss_new();
if(free_num==-1) printf("无解\n");
else if(free_num>=0)
{
int na=0;
printf("PUZZLE #%d\n",++cas);
for(i=0;i<var;i++)
{
na++;
if(na%6==0) printf("%d\n",x[i]);
else
printf("%d ",x[i]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: