题目在这里: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) 连连看的更多相关文章

  1. hdu 1983(BFS+DFS) 怪盗Kid

    http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...

  2. hdu 1175 bfs+priority_queue

    连连看 如上图所示如果采用传统bfs的话,如果按照逆时针方向从(1,1)-->(3,4)搜索,会优先选择走拐四次弯的路径导致ans错误: Time Limit: 20000/10000 MS ( ...

  3. hdu 1044(bfs+dfs+剪枝)

    Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  4. HDU - 1175 bfs

    思路:d[x][y][z]表示以z方向走到(x, y)的转弯次数. 如果用优先队列会超时,因为加入队列的节点太多,无用的节点不能及时出队,会造成MLE,用单调队列即可. AC代码 #include & ...

  5. hdu 1175

    #include <iostream> #include <string> #include <stdio.h> using namespace std; int ...

  6. POJ 2227 The Wedding Juicer (优先级队列+bfs+dfs)

    思路描述来自:http://hi.baidu.com/perfectcai_/item/701f2efa460cedcb0dd1c820也可以参考黑书P89的积水. 题意:Farmer John有一个 ...

  7. 邻结矩阵的建立和 BFS,DFS;;

    邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!-------------------- ...

  8. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  9. hdu 4531 bfs(略难)

    题目链接:点我 第一次不太清楚怎么判重,现在懂了,等下次再做 /* *HDU 4531 *BFS *注意判重 */ #include <stdio.h> #include <stri ...

随机推荐

  1. C# 图像处理:将图像(24位真彩)转为 8位灰度图像 采用了内存法,大大提高了效率

    /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> /// <param name="original&q ...

  2. CSS强制换行和禁止换行代码

    一.强制换行      1.word-break: break-all;       只对英文起作用,以字母作为换行依据.      2.word-wrap: break-word;   只对英文起作 ...

  3. css flex 属性教程

    https://www.zhangxinxu.com/wordpress/2018/10/display-flex-css3-css/#align-self display: flex; flex-w ...

  4. SQL server 基本语法

    文字摘自https://www.cnblogs.com/chaoa/articles/3894311.html 一.定义变量 --简单赋值 declare @a intset @a=5 print @ ...

  5. JS----文档对象模型

    DOM: document object model 文档对象模型提供了一套可以访问和修改HTML文档内容的方法 访问:获取 修改:设置 1 JS要去操作HTML元素,必须要先用JS找到他,转换为JS ...

  6. 用python来分割图片

    程序思路: 此次程序主要是利用PIL(Python Image Libraty)这库,来进行图片的处理.PIL是一个功能非常强大的python图像处理标准库,但由于PIL只支持python2.7.如今 ...

  7. CSS同时选择器

    [CSS同时选择器] 同一个div拥有多个class时,我们可以作多个class作为组合来选择对象.方法就是将多个.className直接连接在一起(中间不能有空格). <p class=&qu ...

  8. angularjs $watch

    参考 https://blog.csdn.net/u010451286/article/details/50635839 scope.$watch("field1 + field2" ...

  9. dedecms 5.7sp2在用type标签时出现调用无效问题

    {dede:type typeid='1'}栏目{/dede:type}   无效 和 {dede:type typeid='1'}[field:typename/]{/dede:type}   有效 ...

  10. Cron 表达式

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: (1) Seconds Minutes Hours DayofMonth Mo ...