题目大意:类似于八皇后。每行每列只能放一个位置,若有墙隔着就互不影响,问最多能放几个。
解题思路:回溯,先读入地图,ok() 分上下左右四个方向判断当前位置是否可以放置,ans 保存最佳答案。tmp 是当前放了多少个。遍历地图,若当前位置可放就标记一下,个数 ++,递归后还原状态。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char map[5][5];
bool vis[5][5];
int n, ans, tmp;
bool ok(int r, int c) {
int up, down, lef, rig;
up = down = lef = rig = 1;
for (int i = 0; i < r; i++) {
if (vis[i][c]) up = 0;
else if (map[i][c] == 'X') up = 1;
}
for (int i = r+1; i < n; i++) {
if (vis[i][c]) down = 0;
else if (map[i][c] == 'X') down = 1;
}
for (int i = 0; i < c; i++) {
if (vis[r][i]) lef = 0;
else if (map[r][i] == 'X') lef = 1;
}
for (int i = c+1; i < n; i++) {
if (vis[r][i]) rig = 0;
else if (map[r][i] == 'X') rig = 1;
}
if (up && down && lef && rig && !vis[r][c] && map[r][c] != 'X') return true;
else return false;
}
void search(int r, int c) {
if (c == n) { r++; c = 0;}
if (r == n) {
if (tmp > ans) ans = tmp;
return;
}
for (int i = r; i < n; i++)
for (int j = c; j < n; j++) {
int t = tmp;
if (ok(i, j)) {
tmp++;
vis[i][j] = 1;
}
search(i,j+1);
tmp = t;
vis[i][j] = 0;
}
}
int main() {
while (scanf("%d", &n) != EOF && n) {
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
scanf("%s", map[i]);
ans = 0;
tmp = 0;
search(0, 0);
printf("%d\n", ans);
}
return 0;
}