深搜水题。
注意可以不用开辅助变量来记录访问情况,直接在原图上记录。如果在这点上放棋子则标记为’0‘。
之后判断一点是否可以放棋子,那么就从此点的上下左右四个方向遍历,如果遍历的途中出现了‘0’,那么说明这一行(列)上已经有旗子了,是一定不能放的。如果在一个方向的遍历上出现‘X’前或遍历完都没有‘0’,那么这个方向是没有约束的,就再看其他三个方向是否可以放。
#include <iostream>
#include<stdio.h>
using namespace std;
int ans,n;
char map[10][10];
bool ok(int x ,int y) //判断是否可以放在这一点
{
for(int i = x + 1; i < n && map[i][y] != 'X';i++)
{
if(map[i][y] == '0')
return false;
}
for(int i = x - 1; i >= 0 && map[i][y] != 'X';i--)
{
if(map[i][y] == '0')
return false;
}
for(int i = y + 1; i < n && map[x][i] != 'X';i++)
{
if(map[x][i] == '0')
return false;
}
for(int i = y - 1; i >= 0 && map[x][i] != 'X';i--)
{
if(map[x][i] == '0')
return false;
}
return true;
}
void dfs(int a)
{
for(int i = 0 ; i < n;i++)
for(int j = 0 ; j < n;j++)
{
if(map[i][j] == '.' && ok(i,j))
{
map[i][j] = '0'; //0表示此点放置了棋子
dfs(a + 1);
map[i][j] = '.';
}
}
if(a > ans) ans = a;
}
int main()
{
while(scanf("%d",&n),n)
{
for(int i = 0 ; i < n;i++)
scanf("%s",map[i]);
ans = 0;
dfs(0);
printf("%d\n",ans);
}
return 0;
}