Poj1222EXTENDED LIGHTS OUT高斯消元

题意:1表示开着,0表示关着。当对某个等打开或关闭时,周围四个灯的状态也会改变,让输出一种开关灯的方式。

搞法1:高斯消元,不过感觉数据应该有问题,我解方程是按一定会存在唯一一组解的情况写的。

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <map>

#include <set>

#include <bitset>

#include <queue>

#include <stack>

#include <string>

#include <iostream>

#include <cmath>

#include <climits>

typedef long long LL;

using namespace std;

int dx[4] = { -1, 0, 1, 0 };

int dy[4] = { 0, -1, 0, 1 };

int a[100][100];

void gao(int pos, int x, int y)

{

	a[pos][x * 6 + y] = 1;

	for (int i = 0; i < 4; i++){

		int xx = x + dx[i]; int yy = y + dy[i];

		if (xx >= 0 && xx < 5 && yy >= 0 && yy < 6){

			a[pos][xx * 6 + yy] = 1;

		}

	}

}







void Gauss(int equ, int var)

{

	int k; int col;

	for (k = 0, col = 0; k < equ&&col < var; k++, col++){

		int kk = k;

		for (int i = k + 1; i < equ; i++){

			if (a[i][col]>a[kk][col]) kk = i;

		}

		if (kk != k){

			for (int j = k; j <= var; j++)

				swap(a[k][j], a[kk][j]);

		}

		if (a[k][col] == 0){

			k--; continue;

		}

		for (int i = 0; i < equ; i++){

            if(i==k) continue;

			if (a[i][col]){

				for (int j = col; j <= var; j++){

					a[i][j] ^= a[k][j];

				}

			}

		}

	}

	for (int i = 0; i<30; i++){

		printf("%d ", a[i][30]);

		if ((i + 1) % 6 == 0) printf("\n");

	}

}

int m[30][30];

int main()

{

	int T;

	cin >> T; int Icase = 0;

	while (T--){

		memset(a, 0, sizeof(a));

		printf("PUZZLE #%d\n", ++Icase);

		for (int i = 0; i < 5; i++){

			for (int j = 0; j < 6; j++){

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

				a[i * 6 + j][30] = m[i][j];

			}

		}

		for (int i = 0; i < 5; i++){

			for (int j = 0; j < 6; j++){

				gao(i * 6 + j, i, j);

			}

		}

		Gauss(30, 30);

	}

	return 0;

}

  

 

搞法2:枚举第一行状态,也就(1<<6)种,下面的开关状态也就确定了。

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <map>

#include <set>

#include <bitset>

#include <queue>

#include <stack>

#include <string>

#include <iostream>

#include <cmath>

#include <climits>

typedef long long LL;

using namespace std;

int dx[4] = { 0, 1, 0, -1 };

int dy[4] = { 1, 0, -1, 0 };

int m[10][10];

int m1[10][10];

int ans[10];

void nong(int x, int y)

{

	m1[x][y] ^= 1;

	for (int i = 0; i < 4; i++){

		int xx = x + dx[i]; int yy = y + dy[i];

		if (xx >= 0 && xx < 5 && yy >= 0 && yy < 6) m1[xx][yy] ^= 1;

	}

}



int gao(int x)

{

	memset(ans, 0, sizeof(ans));

	ans[0] = x;

	for (int i = 0; i < 5;i++)

	for (int j = 0; j < 6; j++) m1[i][j] = m[i][j];

	for (int i = 0; i < 6; i++){

		if (x&(1 << i)){

			nong(0, i);

		}

	}

	for (int i = 1; i < 5; i++){

		for (int j = 0; j < 6; j++){

			if (m1[i - 1][j]){

				ans[i] |= (1 << j);

				nong(i, j);

			}

		}

	}

	int flag = 1;

	for (int i = 0; i < 5&&flag; i++){

		for (int j = 0; j < 6&&flag; j++) if (m1[i][j]) flag = 0;

	}

	return flag;

}



int main()

{

	int T;

	cin >> T;

	int Icase = 0;

	while (T--){

		printf("PUZZLE #%d\n", ++Icase);

		for (int i = 0; i < 5;i++)

		for (int j = 0; j < 6; j++) scanf("%d", &m[i][j]);

		for (int i = 0; i < (1 << 6); i++){

			int k = gao(i);

			if (k){

				for (int j = 0; j < 5; j++){

					for (int k = 0; k < 6; k++){

						if (ans[j] & (1 << k)) printf("1 ");

						else printf("0 ");

					}

					cout << endl;

				}

				break;

			}

		}

	}

	return 0;

}

  

你可能感兴趣的:(extend)