Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175

因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS。

因为与Hdu 1728相比,都要考虑转弯次数,所以在判断转弯的次数上,两者可以相互借鉴。

这一点应该不难想到,在搜索前就应判断两点的值是否相等,以及两点的值中是否有0。如果不相等或其中一值为0,则可以判断是"NO"。

时间虽是10000ms,但只是这样,还是超时。

后来又加了一个数组walk[][],用于记录走到这一点的最小转弯数。当第二次走到这点时,如果第二次的转弯数小于或等于之前的转弯数,则更新数组;否则,不再继续往这个方向走。加上这个数组,再时间上就算初步优化了。

之后又在网上看了看其他人的题解,发现还可以加上这两点:

1.判断回头,即在某个点选择方向时,不往回走。

2.走在一点时,如果此时转弯数为2,那么就要考虑此时与终点是否在同一行或在同一列。如果不在同一列或同一行,则势必要再转一次弯,那就超过2次了。因此当转弯数为2时,两点在同一列或同一行时才能继续往这方向走。

这两点起到了很大的作用,可以大大优化运行时间。

#include <iostream>
#include <cstring>
#include <cstdio> using namespace std; const int MAXN = 1000 + 2;
int map[MAXN][MAXN];
int walk[MAXN][MAXN];
int dir[4][2] = { 1,0, -1,0, 0,1, 0,-1 };
int opposite[4] = { 1,0,3,2 }; // 与i方向相反的值为opposite[i]
int n,m;
bool flag; // 最终能否搜到的标志
int x1,y1,x2,y2; void Dfs( const int x,const int y,const int from,const int step ); void Quick_judge(){ // 初次快速判断能否走到
int i;
int x,y;
if( map[x1][y1]!=map[x2][y2] ){
flag = false;
return ;
}
if( map[x1][y1]==0 || map[x2][y2]==0 ){
flag = false;
return ;
}
for( i=0;i<4;i++ ){
x = x1 + dir[i][0];
y = y1 + dir[i][1];
if( x==x2 && y==y2 ){ //此时已在终点
flag = true;
return ;
}
Dfs( x,y,i,0 ); //开始搜索
}
} void Dfs( const int x,const int y,const int from,const int step ){
if( flag )
return ;
if( x==x2 && y==y2 && step<=2 ) //到达终点
flag = true;
if( map[x][y] ) //非0,无法继续走
return ;
if( walk[x][y]==-1 || step<=walk[x][y] ) //与走到该点的最小转弯数比较
walk[x][y]=step;
else
return ;
if( step==2 ) //如果步数为2,则判断是否在同一行或同一列
if( x!=x2 && y!=y2 )
return ;
int i;
int nextX,nextY;
int nextStep;
for( i=0;i<4;i++ ){
if( i==opposite[from] ) //避免往回走
continue;
nextX = x+dir[i][0];
nextY = y+dir[i][1];
nextStep = step;
if( i!=from ) //转弯
nextStep++;
if( nextX>0 && nextX<=n && nextY>0 && nextY<=m && nextStep<=2 )
Dfs( nextX,nextY,i,nextStep );
}
return ;
} int main()
{
int i,j;
int C;
while( scanf("%d%d",&n,&m)!=EOF && (n||m) ){
for( i=1;i<=n;i++ )
for( j=1;j<=m;j++ )
scanf("%d",&map[i][j]);
scanf("%d",&C);
while(C--){
flag = false;
memset( walk,-1,sizeof(walk) ); //flag与walk[][]的初始化
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
Quick_judge();
if( flag )
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}

Hdu 1175 连连看(DFS)的更多相关文章

  1. hdu 1175 连连看 DFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 解题思路:从出发点开始DFS.出发点与终点中间只能通过0相连,或者直接相连,判断能否找出这样的路 ...

  2. HDU 1175 连连看 (DFS+剪枝)

    <题目链接> 题目大意:在一个棋盘上给定一个起点和终点,判断这两点是否能通过连线连起来,规定这个连线不能穿过其它的棋子,并且连线转弯不能超过2次. 解题分析:就是DFS从起点开始搜索,只不 ...

  3. HDU 1175 连连看(超级经典的bfs之一)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1175 连连看 Time Limit: 20000/10000 MS (Java/Others)     ...

  4. hdu 1175(BFS&DFS) 连连看

    题目在这里:http://acm.hdu.edu.cn/showproblem.php?pid=1175 大家都很熟悉的连连看,原理基本就是这个,典型的搜索.这里用的是广搜.深搜的在下面 与普通的搜索 ...

  5. HDU - 1175 连连看 【DFS】【BFS】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1175 思路 这种题一想到就用搜索, 但是内存是32m 用 bfs 会不会MLE 没错 第一次 BFS的 ...

  6. hdu - 1728逃离迷宫 && hdu - 1175 连连看 (普通bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语. 每个 ...

  7. hdu 1175 连连看 (深搜)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以 ...

  8. HDU 1175 连连看 (深搜+剪枝)

    题目链接 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...

  9. hdu 1175 连连看 DFS_字节跳动笔试原题

    转载至:https://www.cnblogs.com/LQBZ/p/4253962.html Problem Description "连连看"相信很多人都玩过.没玩过也没关系, ...

随机推荐

  1. C#)Windows Shell 编程系列5 - 获取图标

    原文 C#)Windows Shell 编程系列5 - 获取图标 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 编程系列4 - 上下 ...

  2. CI URL 辅助函数 url helper

    URL 辅助函数文件包含一些在处理 URL 中很有用的函数 加载辅助函数 本辅助函数通过如下代码加载: $this->load->helper('url'); 可用函数如下: site_u ...

  3. HDU3966(树链剖分)

    题目:Aragorn's Story 题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有 ...

  4. HDU 2104 hide handkerchief

    题解:由题目可以知道,如果n和m的最大公约数不为1,那么总有箱子是无法遍历的,所以求一遍GCD就可以判断了. 注意点:一定要记住判断是==,在做题时又忘了. #include <cstdio&g ...

  5. HDU2795 billboard【转化为线段树。】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 hhanger大神的题目,水题都得有点思维. 题意:h*w的木板,放进一些1*L的物品,求每次放 ...

  6. 如何设计一个 iOS 控件?(iOS 控件完全解析)

    前言 一个控件从外在特征来说,主要是封装这几点: 交互方式 显示样式 数据使用 对外在特征的封装,能让我们在多种环境下达到 PM 对产品的要求,并且提到代码复用率,使维护工作保持在一个相对较小的范围内 ...

  7. 【转】Ubuntu常用软件合集

    [转]Ubuntu常用软件合集 Ubuntu常用软件合集 我用的使Ubuntu-Kylin14.04,原因呢主要是觉得使本土化的,自带了日历.输入法.优客助手等易于上手的应用.也省的每次安装完原生的系 ...

  8. asp.net core+ef core

    asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一 ...

  9. struts.xml的配置

    <?xml version="1.0" encoding="UTF-8"?> <!--第一行必须这样写,这句话必须放在第一行--> &l ...

  10. 简单的java缓存实现

    扫扫关注"茶爸爸"微信公众号 坚持最初的执着,从不曾有半点懈怠,为优秀而努力,为证明自己而活. 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法 ...