题目描述
假设我们有一个方形的城市,其街道都是直的。在方形地图上,有n行和n列,每个代表一条街道或一堵墙。每个碉堡有4个射击孔,分别正对东西南北方向。在每个射击孔配备一架高射机枪。
我们假设,子弹是如此强大,它的射程可以任意远,并能摧毁它所击中的碉堡。墙也是很坚固的,足以阻止子弹的摧毁。
问题的目标是,在该城市中布置尽可能多的碉堡,而碉堡之间又不会相互摧毁。合理布置碉堡的原则是,没有两个碉堡在同一个水平方向或垂直方向,除非它们之间有墙相隔。在本题中,假定城市很小(最多4×4),而且有子弹不能贯穿的墙壁。
代码
#include<bits/stdc++.h>
#define N 100
typedef long long ll;
using namespace std;
int cMap[5][5];//地图
int iBest;//最优解
int n;//地图的大小
//回溯算法,子集数
//判断在行row和列col处能否配置碉堡
bool CanPut(int row,int col)
{
int i;
//判断col列上的合法性
for(i=row-1;i>=0;i--)
{
if(cMap[i][col]=='o')return false;
if(cMap[i][col]=='X')break;
}
//判断row行上的合法性
for(i=col-1;i>=0;i--)
{
if(cMap[row][i]=='o')return false;
if(cMap[row][i]=='X')break;
}
return true;
}
void solve(int k,int current)
{
int x,y;
if(k==n*n)//整个地图判断完毕
{
//更新最优解
if(current>iBest)
{
iBest=current;return;
}
}
else
{
//将单元转化为x,y坐标
x=k/n;
y=k%n;
if(cMap[x][y]='.'&&CanPut(x,y))//左子树
{
cMap[x][y]='o';//放置一个碉堡
solve(k+1,current+1);
cMap[x][y]='.';//恢复现场
}
solve(k+1,current);//不放置碉堡,右子树
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>cMap[i][j];
}
}
solve(1,1);
cout<<iBest;
}