简单的深度优先搜索HDU1045

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2

题目:类似八皇后问题,图中黑框表示墙,空白表示空,可以摆放炮台,炮台可以攻击同排和同列没有墙隔开的其它炮台,所以两个炮台不能裸露地放在同一排或者同一列.但是,如果中间隔着墙,则可以,我们的目标是使得地图上放上尽可能多的炮台,并且求出最大炮台数量.

简单的深度优先搜索HDU1045_第1张图片

思路:这个题目和八皇后唯一的不同点就是炮台并不攻击对角线,但是却有可能摆放在同一排或者同一列,如果中间隔着墙.题目还是比较有意思的.因为地图最大规模只有4*4,所以完全可以用暴力搜索的办法.用DFS可以解决这个问题,对n*n个格子都判断一遍,如果满足条件,就尝试着摆放在这个位置,当把所有可能摆放的可能性都列举出来的时候,就可以统计出哪种摆放可以使得炮台数最多了.中间需要一个辅助的子函数IsCanPut(x,y)

当前位置可以放置炮台的条件是

case1:当前点不是墙,case2:当前点和之前已经排放的炮台不在同行或者同列出现冲突(即无墙隔开)

#include<iostream>
#include<limits.h>
using namespace std;

int Maxn,n;
char map[5][5];
bool isCanPut(int x,int y)
{
	if(map[x][y]=='X')
		return false ;//can't put in this place
	int i,j;
	for(i=x-1;i>=0;--i)
	{
		if( map[i][y]=='X') break; //if there is a wall,would be ok
		if(map[i][y] == 'o')//this rows exist an bomb
			return false;
	}
	for(j=y-1;j>=0;--j)
	{
		if( map[x][j]=='X')break;
		if( map[x][j]=='o')
			return false;
	}
	return true;
}
void DFS(int num,int Index)//num表示炮台数,Index表示当前索引
{
	if( Index == n*n )
	{
		if(num > Maxn)
			Maxn=num;
	}
	else
	{
		int x=Index / n;
		int y=Index % n;
		if( isCanPut(x,y))
		{
			map[x][y]='o';//puta bomb on this place
			DFS(num+1,Index+1);//search next one,and num add 1
			map[x][y]='.' ; //recover out place
		}
		DFS(num,Index+1);
	}
}
int main()
{
	while(cin>>n && n!=0)
	{
		int i,j;
		Maxn=INT_MIN;
		for( i=0;i<n;++i)
			for(j=0;j<n;++j)
				cin>>map[i][j];
		
		DFS(0,0);//初始状态炮台数,索引都为0
		cout<<Maxn<<endl;
	}
}


你可能感兴趣的:(搜索,ACM,DFS)