题意:
给定一个棋盘,然后在上面放置车;规定如果两个车之间没有墙的话就不能同行或同列;如果中间有墙则不受此限制;问:最多可以放多少个车。
思路:
与以前做过的棋盘问题有些类似,这里需要对每个位置都进行一次穷举;考虑到每个位置都有放一个车或者不放两种选择(当然实际上不是所有位置都可以选择放的),这样可以用dfs穷举所有的方案;对于一个‘.’位置并不一定能放一个车,需要进行检查看是否能放,如果可以放的话,这个位置就可以有两种选择:放或者不放;其它位置必定要选择不放。这就是dfs时状态的转移。
注意:
对与一个‘.’点,如果从它开始往上下左右扩展,没有遇到已经放好了的炮,或者是在遇到炮之前就已经遇到了墙,则这个位置可以放一个车。
检查一个‘.’可不可以放车时,必须是从这个点开始往四周扩展,而不是简单的检查这个点所在的行和列。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int ans,n;
char map[5][5];
int check(int x,int y)
{
int i;
for(i=x-1;i>=0;i--)
{
if(map[i][y]=='X')
break;
if(map[i][y]=='O')
return 0;
}
for(i=x+1;i<n;i++)
{
if(map[i][y]=='X')
break;
if(map[i][y]=='O')
return 0;
}
for(i=y-1;i>=0;i--)
{
if(map[x][i]=='X')
break;
if(map[x][i]=='O')
return 0;
}
for(i=y+1;i<n;i++)
{
if(map[x][i]=='X')
break;
if(map[x][i]=='O')
return 0;
}
return 1;
}
void dfs(int cur,int cnt)
{
if(cur==n*n)
{
if(ans<cnt)
ans=cnt;
return ;
}
int x=cur/n;
int y=cur%n;
if(map[x][y]=='.'&&check(x,y))
{
map[x][y]='O';
dfs(cur+1,cnt+1);
map[x][y]='.';
}
dfs(cur+1,cnt);
}
int main()
{
int i,j;
while(scanf("%d",&n)&&n)
{
for(i=0;i<n;i++)
scanf("%s",map[i]);
ans=0;
dfs(0,0);
printf("%d\n",ans);
}
return 0;
}