HDU 1175 连连看 (DFS+剪枝)
<题目链接>
题目大意:
在一个棋盘上给定一个起点和终点,判断这两点是否能通过连线连起来,规定这个连线不能穿过其它的棋子,并且连线转弯不能超过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+剪枝)的更多相关文章
- hdu 1175 连连看 DFS
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 解题思路:从出发点开始DFS.出发点与终点中间只能通过0相连,或者直接相连,判断能否找出这样的路 ...
- HDU 1175 连连看(超级经典的bfs之一)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1175 连连看 Time Limit: 20000/10000 MS (Java/Others) ...
- hdu 1175(BFS&DFS) 连连看
题目在这里:http://acm.hdu.edu.cn/showproblem.php?pid=1175 大家都很熟悉的连连看,原理基本就是这个,典型的搜索.这里用的是广搜.深搜的在下面 与普通的搜索 ...
- HDU - 1175 连连看 【DFS】【BFS】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1175 思路 这种题一想到就用搜索, 但是内存是32m 用 bfs 会不会MLE 没错 第一次 BFS的 ...
- Hdu 1175 连连看(DFS)
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu ...
- HDU 1175 连连看 (深搜+剪枝)
题目链接 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...
- hdu - 1728逃离迷宫 && hdu - 1175 连连看 (普通bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1728 这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语. 每个 ...
- hdu - 1072(dfs剪枝或bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2:如果之前走过的时间小于这一次, ...
- hdu 1175 连连看 (深搜)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以 ...
随机推荐
- swift 实践- 07 -- UISwitch 开关
import UIKit class ViewController: UIViewController { var uiswitch: UISwitch? override func viewDidL ...
- Confluence 6 使用 Fail2Ban 来限制登录尝试
什么是 Fail2Ban? 我们需要在我们网站中防止密码的暴利破解.Fail2Ban 是一个 Python 的应用来查看日志文件,使用的是正则表达式,同时还可以与Shorewall (或者 iptab ...
- Confluence 6 创建站点的导出文件
希望为你的站点创建一个 XML 导出文件: 进入 > 基本配置(General Configuration) > 备份和恢复(Backup & Restore). 选择 归档到备 ...
- exec与match方法的区别
http://www.cnblogs.com/xiehuiqi220/archive/2008/11/05/1327487.html var someText= "web2.0 .net2. ...
- LeetCode(104):二叉树的最大深度
Easy! 题目描述: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null, ...
- 【python】查找函数定义
help(函数名) 举例:想知道gevnet.Timeout这个函数是怎么用的.help(gevent.Timeout). 之前不知道这样查,每次遇到新函数想知道有哪些参数我都要到网上疯狂查阅文档.现 ...
- mybatis常见错误总结
1. 现象:mybatis xml文件中查询的返回类型写成list或java.util.List时,执行sql时报 java.lang.UnsupportedOperationException错误. ...
- 使用Ultra Librarian将bxl文件转为OrCAD Capture CIS可识别的库文件(OLB)
操作系统:Windows 10 x64 工具1:Ultra Librarian 8.3.89 工具2:OrCAD Capture CIS 16.6-S062 (v16-6-112FF) 关于Ultra ...
- Java File mkdir() mkdirs()
使用mkdir()和mkdirs()创建文件夹的区别. 1.mkdir() 如果父目录不存在,则创建失败. 2.mkdirs() 如果父目录不存在,连同父目录一起创建. 注意,在IO_Study01文 ...
- 006-Python函数
Python函数(def) 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.Python提供了许多内建函数,比如print().但你也可以自己创建函数,这被叫做用户自定义函数.函数能 ...