原题链接
题目大意
在一个边长为 n ( n ≤ 4 ) n(n\le 4) n(n≤4)正方形的城市里,有街道和墙,要在其中放尽量多的碉堡(向四面发射,无法打穿墙),使它们不会攻击到自己城中的碉堡。
解题思路
如下图:
白色区域是街道,黑色区域是墙,右上角的点,就是碉堡,黑色的线所覆盖的区域为可以攻击的范围(不能放其他碉堡的区域),攻击范围不能出界,也不能超过墙。
不妨这么思考:
- 再输入时记录可以放置的位置;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>s;//输入
if(s=='X')
zhangai[i][j]=1;//标记墙
else{
f[++len].i=i;//记录行的位置
f[len].j=j;//记录列的位置
}
}
}
- 枚举每一个位置;
void DFS(int k,int xh){
ans=max(ans,xh);//找最大的答案
if(k>len)//终止条件
return;
int x=f[k].i,y=f[k].j;
if(chk(x,y)){
zhangai[x][y]=2;//标记
DFS(k+1,xh+1);//去下一个位置
zhangai[x][y]=0;//回溯
}
DFS(k+1,xh);//不选
}
- 检查当前位置是否可以放入一个碉堡;
bool chk(int x,int y){
int a=x;
while(a<n){
//向下
if(zhangai[a][y]==2)
return false;//碰到碉堡
else if(zhangai[a][y]==1)
break;//碰到墙
++a;
}
a=x;
while(a>0){
//向上
if(zhangai[a][y]==2)
return false;//碰到碉堡
else if(zhangai[a][y]==1)
break;//碰到墙
--a;
}
int b=y;
while(b<n){
//向右
if(zhangai[x][b]==2)
return false;//碰到碉堡
else if(zhangai[x][b]==1)
break;//碰到墙
++b;
}
b=y;
while(b>0){
//向左
if(zhangai[x][b]==2)
return false;//碰到碉堡
else if(zhangai[x][b]==1)
break;//碰到墙
--b;
}
return true;//四个方向都没有碰到碉堡
}
代码实现
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int zhangai[10][10],n,ans,len;
struct n{
int i,j;
}f[40];
bool chk(int x,int y){
int a=x;
while(a<n){
if(zhangai[a][y]==2)
return false;
else if(zhangai[a][y]==1)
break;
++a;
}
a=x;
while(a>0){
if(zhangai[a][y]==2)
return false;
else if(zhangai[a][y]==1)
break;
--a;
}
int b=y;
while(b<n){
if(zhangai[x][b]==2)
return false;
else if(zhangai[x][b]==1)
break;
++b;
}
b=y;
while(b>0){
if(zhangai[x][b]==2)
return false;
else if(zhangai[x][b]==1)
break;
--b;
}
return true;
}
void DFS(int k,int xh){
ans=max(ans,xh);
if(k>len)
return;
int x=f[k].i,y=f[k].j;
if(chk(x,y)){
zhangai[x][y]=2;
DFS(k+1,xh+1);
zhangai[x][y]=0;
}
DFS(k+1,xh);
}
int main(){
while(true)
{
cin>>n;
if(n==0)
return 0;
char s;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>s;
if(s=='X')
zhangai[i][j]=1;
else{
f[++len].i=i;
f[len].j=j;
}
}
}
DFS(1,0);
cout<<ans<<endl;
ans=0;
len=0;
for(int i=1;i<=len;i++)
f[i].i=0,f[i].j=0;
memset(zhangai,0,sizeof(zhangai));
}
return 0;
}
样例
输入
4
.X…
…
XX…
…
2
XX
.X
3
.X.
X.X
.X.
3
…
.XX
.XX
4
…
…
…
…
0
输出
5
1
5
2
4