hdu 1045 Fire Net(DFS+回溯)

题目描述:给你一个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);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值