题目在这里: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 ;
}

最新文章

  1. 攻城狮在路上(陆)-- 配置hadoop本地windows运行MapReduce程序环境
  2. Unity IOS Build的Graphics API最好是固定Opengl ES 2.0
  3. Xamarin的不归路-使用Gorilla Player实时预览XAML
  4. cocos2d中各种action方法的应用
  5. 深入理解JavaScript系列:史上最清晰的JavaScript的原型讲解
  6. [推荐] kylinPET是一款功能强大的性能测试工具
  7. java_常用数据类型转换基础篇
  8. LR(1)表生成算法演示程序
  9. hdu4622-Reincarnation(后缀自动机)
  10. Turn the corner (三分)
  11. CentOS7+Tomcat 生产系统部署
  12. python利用selenium库识别点触验证码
  13. 2018 HDU多校第三场赛后补题
  14. Linux查询端口是否被占用的四种方法
  15. Confluence 6 反向跟踪
  16. 测试Oracle统计信息的导出导入
  17. Problem B: 平面上的点和线——Point类、Line类 (II)
  18. python中stack在实际中的简单应用之平衡符号
  19. 作业20171123 beta-review 成绩
  20. Markdown 语法笔记

热门文章

  1. php loop循环 拿到键名
  2. jquery 滚动条位置的
  3. 03_java基础(七)之面向对象
  4. sql 求max和min,但是第二大,第二小怎么算?
  5. .sh_history文件的管理机制
  6. python模块部分 re模块 之正则表达式
  7. 【C++】构造函数语意
  8. Vue.Draggable:基于 Sortable.js 的 Vue 拖拽组件使用中遇到的问题
  9. OpenCV轮廓vectorvector
  10. vue params和query传参区别