题目描述:给你一个n x n的矩阵,图中'X'表示wall,'.'表示空地,
若该点不为障碍,则可以放置大炮,大炮可向上下左右4个方向开炮,所以若同一行或同一列存在2门大炮并且他们之间没有障碍,则会出现互相攻击,当然我们不希望这种情况出现。现在问你最多能放置多少门大炮并且他们不能互相攻击。
解题思路:对于每个点,若能放置大炮则能选择放或者不放两种情况,若不能放置大炮则就只有一种情况。由于题目的数据规模很小,n<=4. 所以可以使用暴力搜索。注意回溯的时候要恢复点的状态.
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char map[10][10];
int ans,n;
int judge(int p){//判断该点能否可以放置大炮
int x=p/n,y=p%n;
for(int i=x;i>=0;i--){//向上搜
if(map[i][y]=='X') break;
if(map[i][y]=='@') return 0;
}
for(int i=y;i>=0;i--){//向左搜
if(map[x][i]=='X') break;
if(map[x][i]=='@') return 0;
}
return 1;
}
void DFS(int p,int con){
if(p==n*n){
if(con>ans) ans=con;
return ;
}
int x=p/n,y=p%n;
if(map[x][y]=='.'&&judge(p)){
map[x][y]='@'; //@标记为大炮
DFS(p+1,con+1);
map[x][y]='.';//回溯成原来的状态
}
DFS(p+1,con);//不放大炮
}
int main(){
int m,i,j,k;
while(scanf("%d",&n),n){//n定义成全局变量
memset(map,0,sizeof(map));
ans=0;
for(i=0;i<n;i++){
scanf("%s",map[i]);
}
DFS(0,0);
printf("%d\n",ans);
}
}