<题目链接>

题目大意:
在一个棋盘上给定一个起点和终点,判断这两点是否能通过连线连起来,规定这个连线不能穿过其它的棋子,并且连线转弯不能超过2次。

解题分析:
就是DFS从起点开始搜索,只不过搜索的时候需要记录当前的方向和已经转弯的次数,然后通过题目给定的限制条件进行搜索,判断是否存在从起点到终点转弯次数不超过2次的连线。同时,在转弯次数达到两次的时候,我们可以对搜索树进行可行性剪枝,直接判断转弯两次后,该点与终点是否在同一条直线上,从而减少搜索时间。

#include <bits/stdc++.h>
using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++)
const int N= 1e3+;
int mpa[N][N],vis[N][N];
int n,m,sx,sy,ex,ey;
const int dir[][]={,,,,-,,,-};
bool fp; void dfs(int x,int y,int nowdir,int cnt){
vis[x][y]=;
if(cnt>||fp)return;
if(x==ex&&y==ey){ fp=true;return; }
for(int k=;k<;k++){
int cnt1=cnt;
int nx=x+dir[k][],ny=y+dir[k][];
if(nx<||nx>n||ny<||ny>m||vis[nx][ny])continue;
if((nx==ex&&ny==ey)||!mpa[nx][ny]){
if((nowdir!=-)&&nowdir!=k){
cnt1++;if(cnt1==){
if((nx-ex)!=&&(ny-ey)!=)return; //如果第二次转弯与终点不在同一条直线上
else{ //转了2次后,判断该点是否能够通过这条直线到达终点
int xx=nx,yy=ny;
while(xx>=||xx<=n||yy>=||yy<=m){
if(xx==ex&&yy==ey){ fp=true; return; } //如果通过该直线能够直接到达终点
if(mpa[xx][yy]!=)return; //如果中途除终点外有障碍物
xx=xx+dir[k][],yy=yy+dir[k][]; //沿着这条直线往前走
}
}
}
}
dfs(nx,ny,k,cnt1);
}
}
} int main(){
while(~scanf("%d%d",&n,&m),n||m){
rep(i,,n) rep(j,,m) scanf("%d",&mpa[i][j]);
int q;scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
if(sx<||sx>n||sy<||sy>m||ex<||ex>n||ey<||ey>m||(sx==ex&&sy==ey)){puts("NO");continue;} //判断这两点的位置合不合法
fp=false;
memset(vis,,sizeof(vis));
if(mpa[sx][sy]==mpa[ex][ey]&&mpa[sx][sy])dfs(sx,sy,-,); //如果起点终点相同,且有棋子
fp?puts("YES"):puts("NO");
}
}
}

WA代码

AC代码:

#include <bits/stdc++.h>
using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++)
const int N = 1e3+;
int mpa[N][N];
bool vis[N][N];
int n,m,q,sx,sy,ex,ey;
bool flag;
const int dicx[]={,-,,};
const int dicy[]={,,,-}; void dfs(int x,int y,int dic,int cnt){
if(cnt>||flag) return; //转弯次数大于2或者已经找到就终止
if(cnt==&&(x-ex)!=&&(y-ey)!=) return;//剪枝:判断两次转弯后是否与目标在同一直线上
if(x==ex&&y==ey){ flag=true;return; }
for(int k=;k<;++k){
int xx=x+dicx[k],yy=y+dicy[k];
if(xx<||xx>n||yy<||yy>m||vis[xx][yy]) continue;
if(mpa[xx][yy]==||(xx==ex&&yy==ey)){
vis[xx][yy]=;
if(dic==-||dic==k)dfs(xx,yy,k,cnt);
else dfs(xx,yy,k,cnt+);
vis[xx][yy]=;
}
}
}
int main(){
while(~scanf("%d%d",&n,&m),n||m){
rep(i,,n) rep(j,,m) scanf("%d",&mpa[i][j]);
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
memset(vis,,sizeof(vis));
flag=false;
if(mpa[sx][sy]==mpa[ex][ey]&&mpa[sx][sy])dfs(sx,sy,-,); //初始方向置为-1
flag?puts("YES"):puts("NO");
}
}
}

HDU 1175 连连看 (DFS+剪枝)的更多相关文章

  1. hdu 1175 连连看 DFS

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

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

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

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

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

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

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

  5. Hdu 1175 连连看(DFS)

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu ...

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

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

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

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

  8. hdu - 1072(dfs剪枝或bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2:如果之前走过的时间小于这一次, ...

  9. hdu 1175 连连看 (深搜)

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

随机推荐

  1. struts2 过滤器和拦截器的区别和使用

    java web 过滤器和拦截器的区别和使用  1.1 什么是拦截器:      拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然 ...

  2. Confluence 6 垃圾收集性能问题

    这个文章与 Oracle 的 Hotspot JVM 虚拟机的内存管理为参照的.这些建议是我们在对大的 Confluence 安装实例用户进行咨询服务的时候得到的最佳配置方案. 请不要在 Conflu ...

  3. Confluence 6 尝试从 XML 备份中恢复时解决错误

    错误可能是因为数据库突然不可访问而产生.也有可能是你备份文件有问题,你需要找到你 XML 备份文件中违反数据库规定的记录修改这个记录后再创建一个新的 XML 备份: 在实例开始恢复的时候,请按照下面的 ...

  4. SpringBoot端口和访问路径

    更改启动端口:在application.properties配置文件中修改server.port=9090 更改项目访问路径:在application.properties配置文件中修改server. ...

  5. Android 基础 二 四大组件 Activity

    Activity Intent IntentFilter 一理论概述 一. Activity 用来提供一个能让用户操作并与之交互的界面. 1.1 启动 startActivity(Intent int ...

  6. C语言访问一个链接

    示例代码1: # include <Windows.h> int main(){ system("start http://""www.baidu.com&q ...

  7. easyui组件window拖动时超过浏览器顶部则无法拖回

    项目研发过程中遇到一个问题,easyui的window可以随意拖动或者放大缩小,但是鼠标只有放在“header”上面时鼠标箭头才会变成四个方向的箭头,也就是只有在这时才能拖动窗口:但是当拖动的窗口超过 ...

  8. Oracle unusable index 与unvisible index

    1 可见性 索引的可见性(visibility)指的是该索引是否对CBO优化器可见,即CBO优化器在生成执行计划的时候是否考虑该索引,可以看作是索引的一个属性.如果一个索引可见性属性为:invisib ...

  9. python 利用split读取文本文件中每一行的数字并保存至相应文件夹

    import re from numpy import * def getStr(file_path,file_path1): fp = open(file_path, 'r') op = open( ...

  10. markdown 相关零碎知识

    1.尖括号<>在markdown会被当做html符号,解决办法:用转义字符,如:<测试>  可以写作&lt:测试>