POJ 1222 - EXTENDED LIGHTS OUT
http://poj.org/problem?id=1222
概要
6 * 5 のマス目があり,各マスにはライトがある.
あるマスに触れるとそのマスと隣接する4マスのライトのオンオフが入れ替わる.
各マスのライトのオンオフの初期状態が与えられるので,すべてのライトをオフにするために触れるべきマスを答える.
制約
特になし
解法
poj/1222.cc1 #include <cstdio> 2 #include <vector> 3 using namespace std; 4 5 struct mod 6 { 7 int m; 8 mod(int a) : m(a) {} 9 int operator()(int x) const { return ((x%m)+m)%m; } 10 }; 11 12 static mod M(2); 13 int inv_tbl[2] = {-1, 1}; 14 15 vector<int> gaussian_elimination(vector<vector<int> > a, vector<int> b) 16 { 17 const int N = a.size(); 18 vector<int> sigma(N); 19 for (int i = 0; i < N; i++) { 20 sigma[i] = i; 21 } 22 23 for (int i = 0; i < N; i++) { 24 for (int j = i+1; a[i][i] == 0 && j < N; j++) { 25 swap(a[i], a[j]); 26 swap(b[i], b[j]); 27 swap(sigma[i], sigma[j]); 28 } 29 if (a[i][i] == 0) { 30 continue; 31 } 32 33 const int t = inv_tbl[a[i][i]]; 34 for (int k = i; k < N; k++) { 35 a[i][k] = M(a[i][k] * t); 36 } 37 b[i] = M(b[i] * t); 38 39 for (int j = 0; j < N; j++) { 40 if (i == j) { 41 continue; 42 } 43 const int u = a[j][i]; 44 for (int k = i; k < N; k++) { 45 a[j][k] = M(a[j][k] - u*a[i][k]); 46 } 47 b[j] = M(b[j] - u*b[i]); 48 } 49 } 50 51 for (int i = 0; i < N; i++) { 52 if (a[sigma[i]][sigma[i]] == 0 && b[sigma[i]] != 0) { 53 return vector<int>(); 54 } 55 } 56 return b; 57 } 58 59 int main() 60 { 61 int T; 62 scanf("%d", &T); 63 for (int Ti = 1; Ti <= T; Ti++) { 64 vector<vector<int> > a(30, vector<int>(30, 0)); 65 for (int i = 0; i < 5; i++) { 66 for (int j = 0; j < 6; j++) { 67 for (int d = 0; d < 5; d++) { 68 static const int di[] = {0, -1, 1, 0, 0}; 69 static const int dj[] = {0, 0, 0, -1, 1}; 70 const int k = i+di[d]; 71 const int l = j+dj[d]; 72 if (0 <= k && k < 5 && 0 <= l && l < 6) { 73 a[6*i+j][6*k+l] = 1; 74 } 75 } 76 } 77 } 78 vector<int> b(30); 79 for (int i = 0; i < 30; i++) { 80 scanf("%d", &b[i]); 81 } 82 83 const vector<int> x = gaussian_elimination(a, b); 84 printf("PUZZLE #%d\n", Ti); 85 if (x.empty()) { 86 throw "fail"; 87 } else { 88 for (int i = 0; i < 5; i++) { 89 for (int j = 0; j < 6; j++) { 90 if (j != 0) { 91 putchar(' '); 92 } 93 printf("%d", x[6*i+j]); 94 } 95 putchar('\n'); 96 } 97 } 98 } 99 return 0; 100 }