/* coder: ACboy date: 2010-3-19 result: 1A description: UVa 639 Don't Get Rooked */ #include <iostream> using namespace std; char chess[4][4]; char tempChess[4][4]; int everyPos[70000][16]; int c; // 保存每个子集 void print_subset(int n, int s) { for (int i = 0; i < n; i++) { if (s & (1 << i)) everyPos[c][i] = 1; else everyPos[c][i] = 0; } c++; } // 生成所有的子集 void findAllPos(int n) { for (int i = 0; i < 1 << n; i++) { print_subset(n, i); } } // 检查某一个位置上是否可以放车 int checkRowColumn(int row, int column, int n) { int i; int ok = 1; for (i = column - 1; i >= 0 && tempChess[row][i] != 'X'; i--) { if (tempChess[row][i] == '*') { ok = 0; break; } } if (ok == 0) return 0; for (i = column + 1; i < n && tempChess[row][i] != 'X'; i++) { if (tempChess[row][i] == '*') { ok = 0; break; } } if (ok == 0) return 0; for (i = row - 1; i >= 0 && tempChess[i][column] != 'X'; i--) { if (tempChess[i][column] == '*') { ok = 0; break; } } if (ok == 0) return 0; for (i = row + 1; i < n && tempChess[i][column] != 'X'; i++) { if (tempChess[i][column] == '*') { ok = 0; break; } } if (ok == 0) return 0; return 1; } int checkLegal(int k, int n) { int count = 0; int i; int row; int column; // 对每种可能先把所有的车放到棋盘上,并记录车的个数count for (i = 0; i < n * n; i++) { row = i / n; column = i % n; if (everyPos[k][i] == 1 && tempChess[row][column] == '.') { count++; tempChess[row][column] = '*'; } } // 检查每个车的位置是否合法,如果每个车的位置都合法,则得到一个解 int ok = 1; for (i = 0; i < n * n; ++i) { row = i / n; column = i % n; if (tempChess[row][column] == '*' && checkRowColumn(row, column, n) == 0) { ok = 0; break; } } // 如果所有车的位置都合法则返回车的个数 if (ok) { return count; } else { return 0; } } int main() { int n; #ifndef ONLINE_JUDGE freopen("639.txt", "r", stdin); #endif while (cin >> n) { if (n == 0) break; int i, j; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { cin >> chess[i][j]; } } c = 0; findAllPos(n * n); int max = -1; for (i = 0; i < c; i++) { memcpy(tempChess, chess, sizeof(chess)); int temp = checkLegal(i, n); if (temp > max) max = temp; } cout << max << endl; } return 0; }