zoj 1002【火力网】
描述
给你张N*N的地图,地图上有墙,用"X"表示,有空地,用” . "表示。空地上可以放兵,每个兵可以攻击他的上下左右四条直线范围(不能穿墙)
题目
在防止互相误伤的前提(任何一个兵不在其他兵射程之内),最多摆放多少个兵。
输入输出格式
输入
第一行给出一个数字n
以下n行是N*N的地图(0<=n<=8)
输出
对应每组数据最多能放多少兵,每组数据占一行。
输入输出样例
输入样例1
4 .X.. .... XX.. ....
输出样例1
5
解题思路
每次搜索时定义一个函数判断是否可以放士兵,并继续搜索下去,题目还算是很简单的(当初做了两个小时)。
题解
#include<bits/stdc++.h>
using namespace std;
int n,ans;
char mp[10][10];
bool check(int x,int y)//上下左右搜索,‘D’是士兵,搜到返回false,‘X’就停止
{
for(int i=x;i>=1;i--)
{
if(mp[i][y]=='X')break;
if(mp[i][y]=='D')return false;
}
for(int i=x;i<=n;i++)
{
if(mp[i][y]=='X')break;
if(mp[i][y]=='D')return false;
}
for(int i=y;i>=1;i--)
{
if(mp[x][i]=='X')break;
if(mp[x][i]=='D')return false;
}
for(int i=y;i<=n;i++)
{
if(mp[x][i]=='X')break;
if(mp[x][i]=='D')return false;
}
return true;
}
void dfs(int num,int x,int y)//当前士兵,横坐标,纵坐标
{
if(num>ans)ans=num;//随时更新
for(int i=x;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(check(i,j)&&mp[i][j]=='.')//是否可取
{
mp[i][j]='D';//放士兵
dfs(num+1,i,j);//搜索
mp[i][j]='.';//取消标记,回溯操作
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)//存图
{
for(int j=1;j<=n;j++)
{
cin>>mp[i][j];
}
}
dfs(0,1,1);
cout<<ans;
return 0;
}