题目在这里: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. 【转】Unity网格合并_材质合并

    原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装, ...

  2. spring boot 中使用拦截器

    第一步: 第二步:

  3. EF 数据迁移

    数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migrations -EnableAutomaticMigrations 2.Add-Migration InitialCr ...

  4. git 分支合并develop 重新拉取

    1.本地包 zb-local 上传到对应的线上分支 zb-online cd 进入本地所在文件夹,然后执行下面三项 git add . git commit -m '修改' git push   或者 ...

  5. poj1061-青蛙的约会-(贝祖定理+扩展欧几里得定理+同余定理)

    青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:132162   Accepted: 29199 Descripti ...

  6. Java8 Optional的简单操作

    我们经常会遇到这种情况:首先判断一个对象是否为null,如果不为null,获取一个对象中的一个属性,如果该属性不为null,又获取该属性的属性,如果该属性的属性不为null,又获取属性的属性的属性: ...

  7. UMD模式的js

    (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define( ...

  8. ajax请求是参数问题

    Illegal invocation processData:false,processData用于对data参数进行序列化处理,默认值是true.默认情况下发送的数据将被转换为对象,如果不希望把Fi ...

  9. httpd无法加载libphp5.so模块

    安装httpd-2.2.8 和php-5.2.5,一切顺利. 最后一步重新启动apache报如下错误: httpd: Syntax error on line 53 of /usr/local/apa ...

  10. python中的文件的读写

    python中的 w+ 的使用方法:不能直接 write() 后,在进行读取,这样试读不到数据的,因为数据对象到达的地方为文件最后,读取是向后读的,因此,会读到空白,应该先把文件对象移到文件首位. f ...