HDOJ(HDU).1045 Fire Net [从零开始DFS(7)]

点我挑战题目

从零开始DFS

HDOJ.1342 Lotto [从零开始DFS(0)] — DFS思想与框架/双重DFS

HDOJ.1010 Tempter of the Bone [从零开始DFS(1)] —DFS四向搜索/奇偶剪枝

HDOJ(HDU).1015 Safecracker [从零开始DFS(2)] —DFS四向搜索变种

HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)] —小结:做DFS题目的关注点

HDOJ(HDU).1035 Robot Motion [从零开始DFS(4)]—DFS题目练习

HDOJ(HDU).1241 Oil Deposits(DFS) [从零开始DFS(5)] —DFS八向搜索/双重for循环遍历

HDOJ(HDU).1258 Sum It Up (DFS) [从零开始DFS(6)] —DFS双重搜索/去重技巧

HDOJ(HDU).1045 Fire Net [从零开始DFS(7)]—DFS练习/check函数的思想

题意分析

给出n * n 规模的地图,其中.代表空白区域,X代表墙,求出在满足以下规则的情况下,最多能建立多少座炮楼。

规则:

1.假定炮楼可以四向发射炮弹,要求2个炮楼不能互相打到。(射程无限制)

2.墙可以拦截住炮弹。

相比于之前的dfs题目,本道题的限制要求颇为复杂,首先要求不能互相打到,直观的感觉就是2个炮楼不能处在同一水平/竖直线上。其次要求墙可以拦截子弹,也就是说2个炮楼可以在一条水平/竖直线上的要求就是当且仅当他们中间有墙分隔。

不难从地图中看出,每一个空白的格子均有可能建炮楼(题目中也说了最大个数一定,但位置有可能有多解)。所以可以确定要遍历整张地图,即判断每个格子是否满足建炮楼的条件,会用到HDOJ(HDU).1241 Oil Deposits(DFS) [从零开始DFS(5)] 讨论过的双重for循环遍历整张地图。

回到dfs的核心:递归。这道题有没有递归边界呢?首先由于是对地图进行for循环遍历,也就不会出现越界的情况,越界不会是递归边界。其次这道题要求找出数量的最大值,于是在dfs中肯定会有更新最大值的部分。什么时候进行递归呢?当然就是满足题目所说的建立炮楼的规则的时候。 推算到此,可见难点是如何实现这样规则的检查。

继续看如何实现。按照规则,水平/竖直不能有其他的炮楼出现,不难想到,用for循环分别对上下左右四个方向检查,如果遇到炮楼,则说明这个位置不符合规则,返回false,或者是超越了地图边界,退出循环,再或者是遇到了墙 退出当前循环。 为什么遇到墙就跳出循环了呢? 也不难想到,就算墙后面是炮楼,也是符合规则的,所以干脆遇到墙就跳出循环。

整个程序的架构基本就是这样,下面结合代码,讨论一些小问题。

代码总览

/*
Title:HDOJ.1045
Author:pengwill
Date:2017-2-9
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char mp[5][5];
int visit[5][5];
int n,ans;
void init()
{
ans = 0;
memset(visit,0,sizeof(visit));
for(int i = 0 ;i< n;++i)
for(int j = 0;j <n; ++j){
if(mp[i][j] == 'X') visit[i][j] = 2;
}
}
bool check(int x, int y)
{
if(x<0 || x>=n || y<0 || y>=n) return false;
else return true;
}
bool recheck(int x, int y)
{
if(visit[x][y] == 2 ) return false;
//right
for(int i = x;check(i,y);++i){
if(visit[i][y] == 2) break;
if(visit[i][y] == 1) return false;
}
//left
for(int i = x;check(i,y);--i){
if(visit[i][y] == 2) break;
if(visit[i][y] == 1) return false;
}
//up
for(int i = y;check(x,i);++i){
if(visit[x][i] == 2) break;
if(visit[x][i] == 1) return false;
}
//down
for(int i = y;check(x,i);--i){
if(visit[x][i] == 2) break;
if(visit[x][i] == 1) return false;
}
return true;
}
void dfs(int num)
{ if(num>ans) ans = num;
for(int i = 0;i<n;++i){
for(int j = 0;j<n;++j){
if(recheck(i,j)){
visit[i][j] = 1;
dfs(num+1);
visit[i][j] = 0;
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)&&n){
for(int i = 0;i<n;++i) scanf("%s",mp[i]);
init();
dfs(0);
printf("%d\n",ans);
}
return 0;
}

init函数完成初始化,地图中的墙标记为2(之后建立的炮楼标记为1,没有访问过就是0);然后进入dfs函数,dfs里面先是更新最大值的部分,然后是是双重for循环。当且仅当此点满足recheck时进行递归操作,recheck就是上下左右检查有没有炮楼,当然,如果这点本身就是墙的话,直接return false。 如果满足的话,把这点标记为炮楼(visit[i][j] = 1),继续递归调用dfs,当然不要忘记无后效性(visit[i][j] = 0)。

HDOJ(HDU).1045 Fire Net (DFS)的更多相关文章

  1. HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  2. HDU 1045 Fire Net(DFS)

    Fire Net Problem Description Suppose that we have a square city with straight streets. A map of a ci ...

  3. HDOJ(HDU).1241 Oil Deposits(DFS)

    HDOJ(HDU).1241 Oil Deposits(DFS) [从零开始DFS(5)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架 ...

  4. HDOJ(HDU).1035 Robot Motion (DFS)

    HDOJ(HDU).1035 Robot Motion [从零开始DFS(4)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DF ...

  5. HDOJ(HDU).2660 Accepted Necklace (DFS)

    HDOJ(HDU).2660 Accepted Necklace (DFS) 点我挑战题目 题意分析 给出一些石头,这些石头都有自身的价值和重量.现在要求从这些石头中选K个石头,求出重量不超过W的这些 ...

  6. HDU 1045 Fire Net(dfs,跟8皇后问题很相似)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)   ...

  7. hdu 1045 Fire Net(最小覆盖点+构图(缩点))

    http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS     Memory Limit:32768KB   ...

  8. HDU 1045(Fire Net)题解

    以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...

  9. HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】

    Fire Net Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

随机推荐

  1. Unity制作人物头像小图标和小地图

    人物头像的制作: 在场景中添加人物模型和环境模型 设置人物的layer为Player 在主摄像机的基础上,新建一个次摄像机并将摄像机镜头对准人物面部,调整至合适大小. 设置次摄像机 culling m ...

  2. 【checkbox-group、checkbox】 多项选择器组件说明

    checkbox-group组件包裹checkbox组件的容器 原型: <check-group bindchange="[EventHandle]"> <che ...

  3. Django学习总结之模板templates

    - django模板: templates - 模板分为两个过程: 1, 加载 : loader.get_template('xxx.html') 返回值是一个template对象 2, 渲染 : t ...

  4. lintcode 平面列表

    问题描述: 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 样例: 给定 [1,2,[1,2]],返回 [1,2,1,2]. 给定 [4,[3,[2,[1 ...

  5. [SHELL]输出目录下所有的可执行文件,批量创建用户

    #!/bin/bash IFS=: for folder in $PATH #PATH变量分隔符为: do echo $folder echo ------------------ for file ...

  6. 树(Tree,UVA 548)

    题目描述: 题目思路: 1.使用数组建树 //递归 2.理解后序遍历和中序遍历,建立左右子树 3.dfs深度搜索找出权重最小的路径 #include <iostream> #include ...

  7. Python版本切换和Pip安装

    Python版本切换 现在常用的linux系统中都会默认携带python运行环境,在ubuntu 16.04 和centos 7.3中携带有Python 2.7 和Python3.5两个版本, 默认使 ...

  8. hibernate 异常a different object with the same identifier value was already associated with the session

    在使用hibernate的时候发现了一个问题,记录一下解决方案. 前提开启了事务和事务间并无commit,进行两次save,第二次的时候爆出下面的异常a different object with t ...

  9. SGU 326 Perspective(最大流)

    Description Breaking news! A Russian billionaire has bought a yet undisclosed NBA team. He's plannin ...

  10. LintCode-372.在O(1)时间复杂度删除链表节点

    在O(1)时间复杂度删除链表节点 给定一个单链表中的一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点. 样例 给定 1->2->3->4,和节点 3,删除 ...