题意:在小镇上放机枪,由于某种原因(原因不重要,就是某种原因),两个机枪不能再同一行或者同一列,并且要求小(但是两个之间可以有墙)镇放最多机枪。
自我感觉这道题不像是深搜,更像是遍历+递归(这只是表面,下面会讲清楚,这就是深搜);
最开始我像跑二维数组一样深搜,但是无法判断是否该放置机枪,后来想是不是深搜+背包,但是很遗憾很难判断机枪的取舍。(这些都不重要,重要的是看下面。。)
大致方向:选取一个点,判断这个点能否放机枪,相当于同一个类的操作,所以用递归解决;
这道题的思路:1,递归的每一层遍历小镇找到一个可以放机枪的地方,然后进入下一层,在便利小镇,找到可以放置机枪的地方,直到最后一层。
2,拔掉上一层放置的机枪,重复1步骤,寻找不同的方案。(这层就要用到回溯了,递归+回溯(+本题思想)=深搜)
最好不要看代码,自己先写一遍,思路清了,就很好写的,真的,试一试。
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
char maze[5][5];
int mark[5][5];
int n,max;
bool yes(int x,int y)
{
if(mark[x][y]==1||maze[x][y]=='X') return false;
for(int ii=x;ii<n;ii++)
{
if(mark[ii][y]==1) return false;
else if(maze[ii][y]=='X') break;
}
for(int ii=y;ii<n;ii++)
{
if(mark[x][ii]==1) return false;
else if(maze[x][ii]=='X') break;
}
for(int ii=x;ii>=0;ii--)
{
if(mark[ii][y]==1) return false;
else if(maze[ii][y]=='X') break;
}
for(int ii=y;ii>=0;ii--)
{
if(mark[x][ii]==1) return false;
else if(maze[x][ii]=='X') break;
}
return true;
}
void dfs(int num)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(yes(i,j))//可以放置机枪
{
mark[i][j]=1;
dfs(num+1);
mark[i][j]=0;
}
}
}
if(num>max) max=num;
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
for(i=0;i<n;i++)
{
scanf("%s",maze[i]);
}
max=0;
dfs(0);
printf("%d\n",max);
}
return 0;
}