hdu 1175(BFS&DFS) 连连看
题目在这里:http://acm.hdu.edu.cn/showproblem.php?pid=1175
大家都很熟悉的连连看,原理基本就是这个,典型的搜索.这里用的是广搜.深搜的在下面
与普通的搜索比不同的是要求转折的线不能转折超过两次,就是在结构体中多开一个step(储存转折的次数)和一个dir(记录此刻的方向)
方向初始为-1,当行走一步后的方向与走之前不同的时候,step就应该加一,
然后还要注意的是为了保证得到的是所有的路线中转折次数最小的,这里的visit数组要用来保存每个点的最小转折次数,
所以初始化应该为很大
具体的看code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<climits>
using namespace std;
int map[][],visit[][];
struct point {
int x,y;
int step,dir;//记录转折次数与方向
} ;
int dx[]={,,,-};
int dy[]={,-,,};
int n,m,ex,ey;
int bfs(int sx,int sy)
{
int i;
queue<point>Q;
point next,now;
now.x=sx;now.y=sy;
now.step=;
now.dir=-;
Q.push(now);
while (!Q.empty())
{
now=Q.front();
Q.pop();
if (now.x==ex&&now.y==ey)
return ;
for (i=;i<;i++)
{
next.x=now.x+dx[i];
next.y=now.y+dy[i];
next.step=now.step;
next.dir=i;
if (next.dir!=now.dir&&now.dir!=-)//方向发生变化就加一,但是是第一步的时候并不算是转折
next.step++;
if ((next.x<=n&&next.x>=)&&(next.y<=m&&next.y>=)&&(map[next.x][next.y]==||(next.x==ex&&next.y==ey)))
{
if (next.step<)
{
if (next.step<visit[next.x][next.y]) //让visit数组保存的是到每一点的最小转折次数
{
visit[next.x][next.y]=next.step;
Q.push(next);
}
}
}
}
}
return ;
}
int main()
{
int i,j,t,sx,sy;
while (~scanf("%d %d",&n,&m))
{
if (n==&&m==)
break;
for (i=;i<=n;i++){
for (j=;j<=m;j++){
scanf("%d",&map[i][j]);
}
}
scanf("%d",&t);
while (t--)
{
cin>>sx>>sy>>ex>>ey;
if (sx==ex&&sy==ey)
{
printf("NO\n");
continue;
}
if (map[sx][sy]==||map[ex][ey]==||map[sx][sy]!=map[ex][ey])//这些特殊情况不要漏掉
{
printf("NO\n");
continue;
}
for(i = ; i <= n; i++)
for(j = ; j <= m; j++)
visit[i][j] = ; //初始化为一个很大的数
if (bfs(sx,sy)==)
printf("YES\n");
else
printf("NO\n");
} }
return ;
}
感觉这题深搜比广搜好想一些
无非就是多加了判断条件,注意回溯就行
code
#include<cstdio>
#include<cstring>
using namespace std;
int map[][],visit[][];
int n,m,ex,ey;
int dx[]={,,,-};
int dy[]={,,-,};
int ans;
void dfs(int fx,int fy,int dir,int step)
{
int x,y,i;
if (ans==)return ;
if (step>)return ;
if (step==&&fx-ex!=&&fy-ey!=)return ;
if (fx==ex&&fy==ey&&step<=)
{
ans=;
return ;
}
for (i=;i<;i++)
{
x=fx+dx[i];
y=fy+dy[i];
if (y<=||y>m||x<=||x>n)continue;
if (x==ex&&y==ey)
;
else if (map[x][y]!=)
continue;
if (visit[x][y]!=)continue;
//if (step>=3)continue;
if (dir!=i&&dir!=-)
step++;
visit[x][y]=;
dfs(x,y,i,step);
visit[x][y]=; //注意回溯,step也要回溯
if (i!=dir&&dir!=-)
step--;
}
}
int main()
{
int i,t,j,sx,sy;
while (~scanf("%d %d",&n,&m))
{
if (n==&&m==)
break;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
scanf("%d",&map[i][j]);
}
scanf("%d",&t);
while (t--)
{
memset(visit,,sizeof(visit));
scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
if (sx==ex&&sy==ey)
{
printf("NO\n");
continue;
}
if (map[sx][sy]!=map[ex][ey]||map[sx][sy]==||map[ex][ey]==)
{
printf("NO\n");
continue;
}
ans=;
visit[sx][sy]=;
dfs(sx,sy,-,); if (ans==)
printf("YES\n");
else
printf("NO\n");
}
}
return ;
}
hdu 1175(BFS&DFS) 连连看的更多相关文章
- hdu 1983(BFS+DFS) 怪盗Kid
http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...
- hdu 1175 bfs+priority_queue
连连看 如上图所示如果采用传统bfs的话,如果按照逆时针方向从(1,1)-->(3,4)搜索,会优先选择走拐四次弯的路径导致ans错误: Time Limit: 20000/10000 MS ( ...
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU - 1175 bfs
思路:d[x][y][z]表示以z方向走到(x, y)的转弯次数. 如果用优先队列会超时,因为加入队列的节点太多,无用的节点不能及时出队,会造成MLE,用单调队列即可. AC代码 #include & ...
- hdu 1175
#include <iostream> #include <string> #include <stdio.h> using namespace std; int ...
- POJ 2227 The Wedding Juicer (优先级队列+bfs+dfs)
思路描述来自:http://hi.baidu.com/perfectcai_/item/701f2efa460cedcb0dd1c820也可以参考黑书P89的积水. 题意:Farmer John有一个 ...
- 邻结矩阵的建立和 BFS,DFS;;
邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!-------------------- ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- hdu 4531 bfs(略难)
题目链接:点我 第一次不太清楚怎么判重,现在懂了,等下次再做 /* *HDU 4531 *BFS *注意判重 */ #include <stdio.h> #include <stri ...
随机推荐
- C++ VC实现对话框窗口任意分割
最近写MFC的程序,想在对话框里实现窗口的任意分割.现在网络资料一大抄,找个东西实在麻烦.总算这个很简单,很快就搞定了,写下来做个笔记. 个人认为简单问题最好就是直接贴源代码,一看就明白,说来说 ...
- C# 如何获取屏幕的截图,以及如何在图像上添加文字
关键代码为 Screen sc = Screen.PrimaryScreen; Rectangle rct = sc.Bounds; Image img = new Bitmap(rct.Width, ...
- 认识 Thymeleaf
- webstocket 聊天
/** * 初始化socket **/ function initSocket(index_host){//端口号 if( !window.WebSocket ){ console.log(" ...
- win10 壁纸路径
C:\用户\用户名\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles 原文: https://blog.csdn.net/qq_35040828 ...
- hashcode() equals()
介绍一. hashCode()方法和equal()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致,那么equal()既然已经能实现对比的功能了,为什么还要hashCode()呢? ...
- 关于订单BOM替换组件不成功的问题
替换成功的案例: SELECT * FROM IN_BOM_DETAILS WHERE BOM_ID='00161815_2023_01P19'; --成品编码:000000101011006433P ...
- 大数据入门到精通5--spark 的 RDD 的 reduce方法使用
培训系列5--spark 的 RDD 的 reduce方法使用 1.spark-shell环境下准备数据 val collegesRdd= sc.textFile("/user/hdfs/C ...
- 并发编程(IO多路复用)
阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 异步IO(Asynchro ...
- HDU-2054.A==B?(字符串简单处理)
这道题......被我各种姿势搞死的... 本题大意:给出两个数A和B,判断A和B是否相等,对应输出YES or NO. 本题思路:本题我有两种思路,第一种是直接去除前导零和后导零然后稍加处理比较字符 ...