[解題報告][ZeroJudge][b002] 關燈

終於把上課的矩陣應用在上面了。

解題方法:高斯消去法 + 位元運算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>
using namespace std;
/*
light out puzzle高斯消去法求解
許胖製
2009.11.06
*/
bool A[100][101]; //增廣矩陣
void matrix() { //初始化
int i,j;
memset(A,0,sizeof(A));
A[0][0]=A[0][1]=A[0][10*1+0]=1;
A[9][9]=A[9][8]=A[9][10*1+9]=1;
A[10*9+0][10*9+0]=A[10*9+0][10*9+1]=A[10*9+0][10*8+0]=1;
A[10*9+9][10*9+9]=A[10*9+9][10*9+8]=A[10*9+9][10*8+9]=1;
for (j=1;j<10-1;j++) {
A[j][j]=A[j][j-1]=A[j][j+1]=A[j][j+10]=1;
A[90+j][90+j]=A[90+j][90+j-1]=A[90+j][90+j+1]=A[90+j][90+j-10]=1;
A[10*j][10*j]=A[10*j][10*(j-1)]=A[10*j][10*(j+1)]=A[10*j][10*j+1]=1;
A[10*j+9][10*j+9]=A[10*j+9][10*(j-1)+9]=A[10*j+9][10*(j+1)+9]=A[10*j+9][10*j+8]=1;
}
for (i=1;i<10-1;i++) {
for (j=1;j<10-1;j++) A[10*i+j][10*i+j]=A[10*i+j][10*i+j-1]=A[10*i+j][10*i+j+1]=A[10*i+j][10*(i-1)+j]=A[10*i+j][10*(i+1)+j]=1;
}
}
int main() {
int t,i,j,k;
string s[10];
for (cin>>t;t;t--) {
matrix();
for (i=0;i<10;i++) cin>>s[i];
for (i=0;i<10;i++) for (j=0;j<10;j++) A[10*i+j][100]=((s[i][j]=='#') ? 0:1); //讀入現存盤面
for (i=0;i<100;i++) { //高斯消去法(XOR版)
if (!A[i][i]) { //如果A[i][i]無值的話,去跟下面A[j][i]有的列交換
for (j=i+1;j<101;j++) {
if (A[j][i]) for (k=0;k<101;k++) A[j][k]^=A[i][k]^=A[j][k]^=A[i][k];
}
}
for (j=i+1;j<101;j++) { //如果下面的列A[j][i]有值的話,做XOR運算
if (A[j][i]) for (k=0;k<101;k++) A[j][k]^=A[i][k];
}
}
for (i=99-1;i>=0;i--) { //往回減,如果A[i][j]有值,直接把結果XOR就好了
for (j=i+1;j<101;j++) {
if (A[i][j]) A[i][100]^=A[j][100];
}
}
k=0;
for (i=0;i<101;i++) k+=A[i][100]; //把解相加即為最小步數
cout<<k<<endl;
}
}
,