您的位置:首页 > 其它

poj 1222 EXTENDED LIGHTS OUT

2012-11-23 21:57 295 查看
题意:http://poj.org/problem?id=1222

给一个5*6的01矩阵,0表示灯暗的,1表示灯亮着。矩阵中每个位置表示一个按钮,当按钮按动时它周围(上下左右)的灯变成相反的状态。问怎么按可以将所有的灯都变成暗的。

解题思路:

构建多元一次方程组,求解;使用高斯消元的方法求解。

此外,使用枚举的思路也可以,这里就不介绍了,自己baidu吧

AC代码如下:(代码风格非原创,我第一次写。。。)

View Code

#include<cstdio>                    // poj 1222 EXTENDED LIGHTS OUT
#include<cstring>                    // 160K    0MS    C++
#include<algorithm>                    // 构建矩阵,高斯消元
using namespace std;

const int MAXN = 33;
const int size = 10;

int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
int map[size][size], res[size][size];
int mat[MAXN][MAXN], os[MAXN];

void init()
{
memset( mat, 0, sizeof(mat) );
int i, j, k, tempx, tempy;
for( i = 1; i <= 5; i++ )
{
for( j = 1;j <= 6; j++ )
{
tempx = ( i - 1 ) * 6 + j;
mat[tempx][31] = map[i][j];
mat[tempx][tempx] = 1;
for( k = 0; k < 4; k++ )
{
int x, y;
x = i + dir[k][0];
y = j + dir[k][1];
if( x >= 1 && x <= 5 && y >= 1 && y <= 6 )
{
tempy = ( x - 1 ) * 6 + y;
mat[tempx][tempy] = 1;
}
}
}
}
/*for( i = 1; i <= 30; i++ )            // 构建方程的输出
{
for( j = 1; j <= 31; j++ )
printf( "%d ", mat[i][j] );
puts( "");
}*/
}

void solve()
{
int i, j, row, col, temp;
for( row = 1; row <= 30; row++ )
{
for( i = row; i <= 30; i++ )
if( mat[i][row] )break;
if( i == 31 )continue;
for( j = row; j <= 31; j++ )
swap( mat[row][j], mat[i][j] );
temp = mat[row][row];
for( i = row + 1; i <= 30; i++ )
{
int tmp = mat[i][row];
if( !tmp )continue;
for( j = row; j <= 31; j++ )
mat[i][j] = ( mat[i][j] + mat[row][j] ) & 1;
}
}
/*puts( "******************************************************");
for( i = 1; i <= 30; i++ )                // 调整以后的行列式,阶梯形式
{
for( j = 1; j <= 31; j++ )
printf( "%d ", mat[i][j] );
puts( "");
}*/
os[30] = mat[30][31] / mat[30][30];
for( row = 29; row >= 1; row-- )
{
for( temp = 0, i = row + 1; i <= 30; i++ )
temp += mat[row][i] * os[i];
os[row] = ( mat[row][31] - temp ) / mat[row][row];
os[row] = ( os[row] & 1 ) ? 1 : 0;
}
for( row = 1; row <= 5; row++ )
{
for( col = 1; col <= 6; col++ )
{
temp = ( row - 1 ) * 6 + col;
res[row][col] = os[temp];
//printf( "[%d] : %d\n", temp, os[temp] );
}
}
}

void readcase()
{
int i, j;
for( i = 1; i <= 5; i++ )
for( j = 1; j <= 6; j++ )
scanf( "%d", &map[i][j] );
}

void print( int cas )
{
printf( "PUZZLE #%d\n", cas++ );
int i, j;
for( i = 1; i <= 5; i++ )
{
for( j = 1; j <= 6; j++ )
printf( "%d ", res[i][j] );
puts("");
}
}

int main()
{
int T, cas;
scanf( "%d", &T );
for( cas = 1; cas <= T; cas++ )
{
readcase();
init();
solve();
print( cas );
}
return 0;
}


利用高斯消元求解,可以用来熟悉高斯消元的基本格式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: