这是一道类似于N皇后的问题,叫我们将车放到小棋盘上面去,规则也类似,让每个车都不能攻击到其他车,
然后有墙阻隔,车是不能攻击到墙后的车的。参考了knowledgetime大神的代码,用回溯法来解决这个问题。
定义一个mat数组,先将棋盘的情况读入,如果是 ’ .’就将mat[i][j] 置为1,X则置为0;然后有一个放置
的函数,对于i行,j列,(I,j都从0开始)我们向上与向左搜索,判断是否该行或该列是否已经放置车,如果没
有我们就可以将车放上去,然后将mat的值改成 -1。因为墙是置为0的,所以遇到有墙,而墙的同一侧没有东
西,我们也是可以放置车的。最后的工作就是每行逐列地搜索,不断更新max的值,搜完所有的情况输出。
#include<cstdio>
#include<cstring>
#include<cstdlib>
const int MAXN = 10;
char s[MAXN];
int n, mat[MAXN][MAXN];
bool place( int R, int C)
{
for( int i = R; i >= 0; i --) {
if( mat[i][C] < 0) return false;
else if( !mat[i][C] ) break; //有墙
}
for( int j = C; j >= 0; j --)
{
if( mat[R][j] < 0) return false;
else if( !mat[R][j]) break; // 有墙
}
return true;
}
int dfs( int i, int j)
{
int cnt = 0, max = 0;
while( i < n)
{
if( mat[i][j] && place( i, j) )
{
mat[i][j] = -1; //已经放置
cnt = dfs( i, j + 1) + 1;
if( cnt > max) max = cnt;
mat[i][j] = 1; // 恢复原来的情况
}
if( j >= n - 1) {
i ++;
j = 0;
}
else j ++;
}
return max;
}
int main()
{
while( scanf( "%d", &n), n)
{
for( int i = 0; i < n; i ++)
{
scanf( "%s", s);
for( int j = 0; j < n; j ++)
{
if( s[j] == '.')
mat[i][j] = 1;
else mat[i][j] = 0;
}
}
printf( "%d\n", dfs( 0, 0));
}
return 0;
}