题意: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;
}