上1行と左1列を全通り試す。
個人的にはMidより簡単な気がする。
int H, W; char rev(char c) { return c == '*' ? '.' : '*'; } void turn(vector<string> &s, int i, int j) { const int di[] = {-1, -1, -1, 0, 0, 0, +1, +1, +1}; const int dj[] = {-1, 0, +1, -1, 0, +1, -1, 0, +1}; for (int d = 0; d < 9; ++d) { int ni = i + di[d]; int nj = j + dj[d]; if (ni < 0 || nj < 0) continue; if (H <= ni || W <= nj) continue; s[ni][nj] = rev(s[ni][nj]); } return ; } const int inf = 1 << 29; int f(vector<string> s) { int cnt = 0; for (int i = 0; i < (int)H; ++i) cout << s[i] << endl; cout << endl; for (int i = 1; i < (int)H; ++i) { for (int j = 1; j < (int)W; ++j) { if (s[i - 1][j - 1] == '.') { turn(s, i, j); ++cnt; } } } if (count(s.begin(), s.end(), string(s[0].size(), '*')) != (int)s.size()) { return inf; } return cnt; } class LightedPanels { public: int minTouch(vector <string> B) { int mn = inf; H = B.size(); W = B[0].size(); const vector<string> tmp = B; for (int a = 0; a < (1 << H); ++a) { for (int b = 0; b < (1 << W); ++b) { int cnt = 0; B = tmp; for (int i = 0; i < (int)H; ++i) { if (a & (1 << i)) { turn(B, i, 0); ++cnt; } } for (int j = 1; j < (int)W; ++j) { if (b & (1 << j)) { turn(B, 0, j); ++cnt; } } mn = min(mn, f(B) + cnt); } } return mn == inf ? -1 : mn; } };