DFS中的奇偶剪枝

hdoj1010 Tempter of the Bone(迷宫问题dfs,奇偶剪枝) 迷宫问题。 这类问题接触的少,但仔细审题就能看出要用dfs。欢天喜地写出代码,结果超时了。 百度了一下,惊讶的发现差了从没听过的奇偶剪枝操作。 代码有借鉴的地方。 #include #include #include using namespace std; int n,m,t; char maze[8][8]; int v[8][8]; int d[4][2]={-1,0,1,0,0 阅读详情

本博客由搜集资料拼凑而成。。。

首先介绍什么是奇偶剪枝:

奇偶剪枝

【问题描述:】

给定一个N*M的迷宫以及起点和终点,迷宫中有一些障碍无法穿过,问能否不重复也不停留地在刚好一共走T步出迷宫。

 

【问题分析:】

先来看下这张图片:


也就是说当要走偶数步而规定的步数是奇数,或者要走奇数步而规定的步数是偶数,都是不可能到达的,如果要想到达,则要走的步数和规定的步数的奇偶性应该一致。又可知,奇偶性一致的两个数的差或者和都是偶数。(下面有大用处)

 

例如下图:设S点坐标为(sx,sy),D点坐标为(dx,dy),.表示通路,X表示障碍。

S...
....
....
...D

可知从S走到D的最短距离为abs(sx-dx)+abs(sy-dy);

S..X

..XX
.X.X
...D

上面这个迷宫中存在一些障碍,假设当前已走step步,则还剩下t-step步,设当前点到终点的最短距离为abs(si - dx)+ abs(sj - dy),则两者的奇偶性一定一致的(由上面那段话可知)并且前者一定大于等于后者(剩下要走的步数大于等于该坐标到终点的最短距离),只有这样,才能够到达。也就是tem = t – step – (abs(si - dx)+ abs(sj - dy)),tem >= 0 && tem % 2 == 0.

(http://blog.youkuaiyun.com/i1020/article/details/54918472)

其中奇偶剪枝关键便是这句话

ans = t - step - abs(x-ex)-abs(y-ey);
if(ans<0||ans&1)return;
//t为限制的步数,step为已经走过的步数,x,y当前位置
//ex,ey为终点位置

例题:

                                                                                                                       Tempter of the Bone(HDU-1010)

                                                              Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Problem Description

The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

 

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.

 

 

 

Input

The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

 

'X': a block of wall, which the doggie cannot enter; 

'S': the start point of the doggie; 

'D': the Door; or

'.': an empty block.

 

The input is terminated with three 0's. This test case is not to be processed.

 

 

 

Output

For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.

 

 

 

Sample Input

4 4 5

S.X.

..X.

..XD

....

3 4 5

S.X.

..X.

...D

0 0 0 

 

Sample Output

NO

YES 

题意:在一个坐标内,给定起点和终点,问能否恰好在t时刻到达终点。

一开始直接搜索超时,后来各种剪枝还是超时,就单单没有判断奇偶性。判断后又忘记每次初始化访问数组,错了很多次

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int n,m,t;//n,m数组大小,t限制时间
char mp[20][20];//地图
int vis[20][20];//访问数组
int solve;//判断能否到达的变量
int sx,sy,ex,ey;//起点坐标,终点坐标
int dirx[4] = {0,0,1,-1};
int diry[4] = {1,-1,0,0};//方向数组
void dfs(int x,int y,int s){
    int i;
    int xx,yy;
    if(x==ex&&y==ey&&s==t){
        solve = 1;
        return;
    }//恰好符号条件就将solve变成1
    int ans = t-s-abs(x-ex)-abs(y-ey);
    if(ans&1||ans<0)return;//奇偶剪枝
    //if(s>=t)return;
    if(solve==1)return;//如果发现之前已经符合条件了,就直接返回就可以
    for(i = 0; i < 4; i++){
        xx = x + dirx[i];
        yy = y + diry[i];
        if(xx>=0&&xx<n&&yy>=0&&yy<m&&vis[xx][yy]==0&&mp[xx][yy]!='X'){
            vis[xx][yy] = 1;
            dfs(xx,yy,s+1);
            vis[xx][yy] = 0;//普通DFS
        }
    }
}
int main(){
    int i,j;
    while(~scanf("%d%d%d",&n,&m,&t)){
        if(n==0&&m==0&&t==0)break;
        solve = 0;
        for(i = 0; i < n; i++)
            scanf("%s",mp[i]);
        for(i = 0; i < n; i++){
            for(j = 0; j < m; j++){
                if(mp[i][j]=='S'){
                    sx = i;
                    sy = j;
                }
                if(mp[i][j]=='D'){
                    ex = i;
                    ey = j;
                }//记录始末位置
            }
        }
        if(abs(sx-ex)+abs(sy-ey)<=t){//判断如果从起点到终点的最短距离都比t大说明一定到达不了,所以进行判断以优化
            memset(vis,0,sizeof(vis));
            vis[sx][sy] = 1;
            dfs(sx,sy,0);
        }
        if(solve)
            printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}



HDOJ1010 Tempter of the Bone(DFS,奇偶剪枝) HDOJ 1010 先解释一下奇偶剪枝: 这个题目用一般的搜索无法完成,因为题目要求在指定的时间内完成,所以只好一步一步来啦,用DFS解决 但是如果这样结果会超时,网上说是用一种奇偶剪枝的方法来间断搜索时间,下面是剪枝的简单理论,一看就懂: 把map看作 0 1 0 阅读详情

相关推荐

轴承寿命预测实战:手把手教你用IEEE PHM2012数据集训练模型(附Python代码)

本文详细介绍了如何利用IEEE PHM2012数据集构建轴承剩余寿命预测模型,从数据预处理、特征工程到LSTM模型训练与部署,提供了完整的Python代码实现。通过实战案例,帮助读者掌握预测性维护中的关键技术,提升工业设备的运行安全与效率。

weixin_29186249的博客 311

奇偶剪枝--非常巧妙的技巧

奇偶剪枝是数据结构的搜索中,剪枝的一种特殊小技巧。 奇偶剪枝的原理 两点之间的曼哈顿距离为奇数, 则只能在奇数步内到达,偶数同理。 即:假设起点为(x1,y1),终点为(x2,y2),给定 step 步恰好走到终点,则 abs(x2-x1)+abs(y2-y1) 与 step 同奇偶。 证明 以图代证: 一开始没有障碍,“#”表示可以走,S 到 E 的最短步数为6。 接下来有障碍了,要绕路。 黑色的路是最短路,蓝色是最短路的平移,不影响步数,所以只有红色的路是绕的路即多走的路。 通过观察,可以发现一.

叶底藏花~的博客 534

常学常新:《Attention Is All You Need》万字解读!

常学常新:《Attention Is All You Need》万字解读!

hunteritself的博客 3640

【总结】DFS常用技巧详解 —— 奇偶剪枝

剪枝 剪枝策略就是在搜索过程中利用过滤条件来剪去完全不用考虑(已经判断这条路走下去得不到最优解)的搜索路径,从而避免了一些不必要的搜索,大大优化了算法求解速度,还保证了结果的正确性。 简单的说就是把不可行的一些情况剪掉,例如走迷宫时运用回溯法,遇到死胡同时回溯,造成程序运行时间长。剪枝的概念,其实就跟走迷宫避开死胡同差不多。若我们把搜索的过程看成是对一棵树的遍历,那么剪枝顾名思义,就是将树中的...

360°顺滑 1142

别再傻傻分不清了!Anaconda和Miniconda到底选哪个?附保姆级安装与镜像源配置(Windows/Mac)

本文详细解析了Anaconda和Miniconda的核心差异,包括体积、预装内容、系统资源占用等关键维度,并提供了针对不同需求的决策框架。附有Windows和Mac双平台的详细安装与配置指南,帮助用户根据实际需求选择最适合的conda工具,提升开发效率。

weixin_30315723的博客 426

VSCode + QMT 量化交易完整解决方案!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1327

2.奇偶性剪枝

题目: 分析: 代码: import java.util.ArrayList; import java.util.Scanner; public class Main { /* * 最优性剪枝(每次遍历将 多于 当前最优解步数的 直接剪掉) * 问题:找出起点S到终点T的最少步数 测试数据1 4 4 5 S.X. ..X. ..XD .... * */ static char[][] g;//迷宫 static int n;//行 static int m;//.

sunnnnh的博客 335

Leads、SDR、MQL、SQL、L2C术语概念,线索创建与清洗、线索分级模型、线索流转策略、线索的统计与分析

CRM中的“Leads”是什么?笔者在文中不仅较为全面地介绍了相关术语概念,还分析了线索的创建与清洗、线索的分级模型、线索流转策略以及线索的统计与分析。

盼盼学士 5954

奇偶剪枝

什么是奇偶剪枝? 把矩阵看成如下形式: 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 从为 0 的格子走一步,必然走向为 1 的格子 。 从为 1 的格子走一步,必然走向为 0 的格子 。 即: 从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。所以当遇到从 0 走向 0 但是要

Lngxling的博客 493

华为OD机试真题 新系统2026-04-08 C语言 实现【直捣黄龙】

小王在玩一款叫做直捣黄龙的小游戏,在该游戏中他需要从入口位置进入敌营,绕过哨兵的层层封锁,达到敌军司令部实施斩首行动。 敌军阵营是一个n*n的矩阵,入口在坐标(0,n/2),敌军司令部在坐标(n-1,n/2),每个哨兵警戒以自己为中心的9宫格,一旦被哨兵发现则行动失败。

MISAYAONE的博客 182

6、探索音乐结构中的统一性:贝多芬《英雄交响曲》第一乐章的深度剖析

本文深入剖析了贝多芬《英雄交响曲》第一乐章的音乐结构,探讨其统一性的来源及表现形式。通过主题与动机、和声与调性、旋律与节奏、织体与动态等多方面的分析,揭示了这部作品在技术层面和情感表达上的卓越成就。

b9c0d的博客 518

hdu1010(dfs + 奇偶性剪枝)

奇偶性剪枝是一种可行性剪枝,使得搜索的速度大幅度加快。 (注意:这道题目没有来回走的情况,考虑来回走的情况能不能用搜索写) 假设两个点的曼哈顿距离(abs(x1 - x2) + abs(y1 - y2))为dis。 我们可以找到一个规律:不管我们怎么走,从这个点走到另外一个点的步数为X,那么一定有X - dis = 偶数。 所以如果X - dis为奇数的话,就说明就算不管继续往下怎么走,都不可能走到。 假设我们现在还能走T步的话,只需要判断T - dis是否是偶数就可以,如果是奇数,就肯定走不到,可以直接r

weixin_45925735的博客 429

添加USB wifi驱动到RK3568

在日常开发中我们经常需要用到wifi功能,一般来说soc厂家都会事先做好了几个厂家的wifi驱动在内核源码目录下,我们只需要按原理图配置对应的设备树即可。常用的wifi的接口有:USBSDIOPCIE下面来介绍这这种接口是如何使用wifi芯片。提示:以下是本篇文章正文内容,下面案例可供参考本小节介绍了一个配置一个USBwifi驱动的整个流程,并没有介绍到SDIO,下小节基于AP6256介绍如何使用。

qq_24093081的博客 2049

HDU 1010 DFS+奇偶剪枝

Tempter of the Bone DFS+奇偶剪枝

果冻虾仁 3174

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

HDU 1010 dfs 奇偶剪枝

原文链接: HDU 1010 dfs 奇偶剪枝 上一...

阿豪 154

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Tempter of the Bone(DFS + 奇偶剪枝,好题)

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 39780    Accepted Submission(s): 10761 原题链接:点击打开链接 Problem Descript

cs_zlg的专栏 1360

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

HDOJ 1010迷宫 +dfs+奇偶剪枝

问题:链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010  小狗在古老的迷宫中发现了一个骨头,这使他迷恋了很多。 然而,当他拿起来,迷宫开始摇动,小狗可以感觉到地下沉。 他意识到骨头是一个陷阱,他拼命地走出了这个迷宫。 迷宫是M的大小为N的矩形。迷宫里有一扇门。 一开始,门关闭,它将在第T秒打开一段时间(不到1秒)。 因此,小狗不得不在第T秒

不平凡的博客 896

HDU1010 Tempter of the Bone(深度优先搜索DFS+奇偶性剪枝)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题意:       给定一个迷宫图,问T步能否找到门。 分析:       这是个DFS的奇偶剪枝问题,先附张图。  对于代码中的解释 其中t-w为剩余的步数或者说时间, s1+s2为剩余步数, 如果走偶数步要求的时间是奇数,或者走奇数步要求的时间是偶数,都明显不可行 而轻...

Sean 294

HDOJ1010+DFS+奇偶剪枝的个人小总结

DFS 所谓深度优先搜索,在遇到迷宫等类型的题目的时候就是每一个格子进去都尝试着进入,然后判断。一般采用递归的方法。由于采用了递归,所以程序上要进行一些优化: 判断是否为奇数或偶数时 用 temp&1 而不用temp%2 ==1 尽量用scanf读入而不用cin 可以利用奇偶剪枝法,对很对数据进行处理,减少计算量 奇偶剪枝法: 所谓奇偶剪枝法就是假定一个矩阵中的元素为: 0 1 0 1...

qq_41286749的博客 248

DFS奇偶剪枝

DFS奇偶剪枝 HDU1010题,无线TLE;百度一下学习了奇偶剪枝; 开始: 从一个点(x,y)到达终点(ex,ey)的最短距离是S 无论S是奇数还是偶数,要想到达终点的任意方案数中,路径长度一定是S+extra,extra必须为偶数(画几遍图没找到奇数画法); 好像可以用于BFS,这个还没用过; 就HDU1010题,当前已经走过time秒,总的时间为t秒;剩余时间为t-time秒 t-time...

weixin_43550608的博客 175

Tempter of the Bone-深度优先中的奇偶剪枝问题

<br />感觉总是在遇到深度优先搜索这类问题的时候容易犯迷糊,这道题很久以前就提交过代码了,但是一直都没通过。总返回超时,今天闲着没事,回头仔细看了一下。解题思路很简单:深度优先搜索+搜索剪枝。那问题就出在对搜索的优化上面。刚开始只想到了一个地方,那就是如果empty block的数目小于门关闭的时间的话,那肯定是出不去的。其实还有另一处可以优化,那就是路径奇偶性的问题。如下面的一个图:<br />0,1,0,1,0 1,0,1,0,1 0,1,0,1,0 1,0,1,0,1 <br /> <br

Just keep moving! 411

HDU 1010( DFS+奇偶剪枝)

0 1 0 1 0 11 0 1 0 1 00 1 0 1 0 11 0 1 0 1 00 1 0 1 0 1 从 0->1 需要奇数步从 1->0 需要偶数步那么设所在位置 (si,sj) 与 目标位置 (di,dj)如果abs(si-sj)+abs(di-dj)为偶数,则说明 abs(si-sj) 和 abs(di-dj)的奇偶性相同,需要走偶数步如果abs(si-sj)+abs(di-d奇偶

积跬步致千里 787

hdu1010(dfs和奇偶剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意: 就是看指定的迷宫内存不存在一条路是指定步数的路径从起点到终点。 题目思路: 就是利用dfs进行搜索 然后利用奇偶剪枝来进行减少搜索时间 简单说下奇偶剪枝: 给我们一个地图,如: S.X. …X. …XD … 我们可以看成: 0101 1010 0101 1010 起点所在的为0,终...

zhoupingqi2017的博客 183

dfs之奇偶剪枝

杭电1010 dfs杭电1010 这道经典的dfs剪枝例题引出奇偶剪枝: 先看ac码: #include<iostream> #include<algorithm> #include<string.h> #include<math.h> using namespace std; int a,b,c,x,y,zx,zy; char s[10][10]; int zb[]= {-1,1,0,0},yb[]= {0,0,1,-1}; int flag=0; void

yyj的博客之旅 152

hdu-1010 Tempter of the Bone(DFS+奇偶剪枝)

hdu-1010 Tempter of the Bone(DFS+奇偶剪枝)题目描述 Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 109915 Accepted Subm

oYinGui1 862
上一篇: 双六问题(扩展欧几里得模板)
下一篇: HDU 2059 龟兔赛跑(DP)
Guuuuuu老师儿
博客等级 码龄9年 259粉丝 718原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值