题目链接:https://www.luogu.org/problem/show?pid=1649

历经千辛万苦,我总算是把这个水题AC了,现在心里总觉得一万只草泥马在奔腾;

这是一道很明显的BFS,然后我也明显的看出来了

但是,我就是WA了很久很久,在调试第一个晚上后,我发现读入是存在空格的,而不是数据问题

然后第二个问题就是,BFS找到的第一个终点不一定就是最优的答案(当然第二个问题是我重新打了一次猛然发现之前没注意的一点)

注意到这两点,其实这道题就没难度了

然后这道题的处理需要注意一个地方就是转弯,有两种方式来处理这个转弯

一:开结构体数组,记录当前点前驱的序号,然后看前驱的坐标和下一个位置的坐标是否有横纵坐标中的一个相等

二:开队列,然后用结构体,结构体里存一个direction(方向),然后定义上下左右分别对应1,2,3,4,如果当前点的方向和下一个拓展的方向相同,如果相同则拓展的方向没转弯

当然如果用数组的话会有一点的麻烦,用队列的话代码难度小一点而且更方便不会超时,我之前用数组也是超过时的,所以还是建议用队列

PS:接下来这个代码在洛谷上是可以过的,因为数据较水

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<string>
#define maxn 105
using namespace std; const int dx[]={,-,,,};
const int dy[]={,,,-,}; struct node{
int x,y,s,d;//坐标,步数,方向
}; queue<node>q;
int n,map[maxn][maxn],vis[maxn][maxn];
int sx,sy,fx,fy,ans=; void init()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
char a;
scanf("%c",&a);
while(a!='A'&&a!='B'&&a!='x'&&a!='.')
{
scanf("%c",&a);
}
if(a=='A'){
sx=i;sy=j;
}
if(a=='B'){
fx=i;fy=j;
}
if(a=='x'){
map[i][j]=;
}
}
} int main()
{
init();
vis[sx][sy]=;
q.push((node){sx,sy,,});
while(!q.empty())
{
node e=q.front();
q.pop();
vis[e.x][e.y]=;
for(int i=;i<=;i++)
{
int zx=e.x+dx[i],zy=e.y+dy[i];
if(zx<||zx>n||zy<||zy>n)continue;
if(map[zx][zy]==&&vis[zx][zy]==){
if(i==e.d||e.d==){
q.push((node){zx,zy,e.s,i});
}else {
q.push((node){zx,zy,e.s+,i});
}
}
}
if(e.x==fx&&e.y==fy){
ans=min(ans,e.s);
}
}
if(ans<=)printf("%d",ans);
else printf("-1");
}

但是仔细斟酌,如果是100*100的图,而没有障碍,那么普通的队列是会爆的,这个可以自己尝试

所有改成优先队列做

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<string>
#define maxn 105
using namespace std; const int dx[]={,-,,,};
const int dy[]={,,,-,}; struct node{
int x,y,s,d;//坐标,步数,方向
bool operator< (const node &a)const{
return s>a.s;}
}; priority_queue<node>q;
int n,map[maxn][maxn],vis[maxn][maxn];
int sx,sy,fx,fy,ans=; void init()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
char a;
scanf(" %c",&a);
while(a!='A'&&a!='B'&&a!='x'&&a!='.')
{
scanf("%c",&a);
}
if(a=='A'){
sx=i;sy=j;
}
if(a=='B'){
fx=i;fy=j;
}
if(a=='x'){
map[i][j]=;
}
}
} int main()
{
init();
vis[sx][sy]=;
q.push((node){sx,sy,,});
while(!q.empty())
{
node e=q.top();
q.pop();
vis[e.x][e.y]=;
for(int i=;i<=;i++)
{
int zx=e.x+dx[i],zy=e.y+dy[i];
if(zx<||zx>n||zy<||zy>n)continue;
if(map[zx][zy]==&&vis[zx][zy]==){
if(i==e.d||e.d==){
q.push((node){zx,zy,e.s,i});
}else {
q.push((node){zx,zy,e.s+,i});
}
}
}
if(e.x==fx&&e.y==fy){
//if(e.s>=ans)
ans=min(ans,e.s);break; }
}
if(ans<=)printf("%d",ans);
else printf("-1");
}

真·AC

这个代码的区别就是优先队列,和跳出语句,其中跳出的时候要注意特例,可能会存在到终点不用转弯的线上的点的转弯次数相同但是来源到终点却有转弯和不转弯的情况,,所以要特判一个当现在的值会大于等于ans就跳出

特例

。。。。A

。。。。。

。B 。。。

到B左边的点时,转弯一次,到b右边的点时,转弯一次,但是左边点会多转一次,所以要特判一下

[洛谷1649]障碍路线<BFS>的更多相关文章

  1. P4554 小明的游戏 (洛谷) 双端队列BFS

    最近没有更新博客,全是因为英语,英语太难了QWQ 洛谷春令营的作业我也不会(我是弱鸡),随机跳了2个题,难度不高,还是讲讲吧,学学新算法也好(可以拿来水博客) 第一题就是这个小明的游戏 小明最近喜欢玩 ...

  2. 洛谷P1038 神经网络(bfs,模拟,拓扑)

    题目背景 人工神经网络(Artificial Neural NetworkArtificialNeuralNetwork)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸 ...

  3. 洛谷 P4201 设计路线 [NOI2008] 树形dp

    正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...

  4. 洛谷——P1958 上学路线_NOI导刊2009普及(6)

    P1958 上学路线_NOI导刊2009普及(6) 题目描述 你所在城市的街道好像一个棋盘,有a条南北方向的街道和b条东西方向的街道.南北方向的a条街道从西到东依次编号为l到a,而东西方向的b条街道从 ...

  5. 洛谷 P2296 寻找道路 —— bfs

    题目:https://www.luogu.org/problemnew/show/P2296 第一次用 Emacs 对拍,写了半天: 注意那个 is 赋值的地方很容易错,千万别反复赋值: 一道水题写了 ...

  6. 洛谷 P2437 蜜蜂路线

    P2437 蜜蜂路线 题目描述 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线? 输入输出格式 ...

  7. 洛谷P2770 航空路线问题(费用流)

    传送门 完了这题好厉害……字符串什么的好麻烦…… 要求从$1$到$n$的路径,不重复,经过边数最多 每一个点拆成两个,$A_i,B_i$,然后$A_i$到$B_i$连容量为$1$,费用为$1$的边,保 ...

  8. 洛谷P2770 航空路线问题(费用流)

    题意 $n$个点从左向右依次排列,有$m$条双向道路 问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点 Sol 首先,问题可以转化为求两条互不相交的路径,使得点数最多 为了满足 ...

  9. 洛谷 P2770 航空路线问题【最大费用最大流】

    记得cnt=1!!因为是无向图所以可以把回来的路看成另一条向东的路.字符串用map处理即可.拆点限制流量,除了1和n是(i,i+n,2)表示可以经过两次,其他点都拆成(i,i+n,1),费用设为1,原 ...

随机推荐

  1. BUI Webapp用于项目中的一点小心得

    接触BUI也有一段时间,也用在了移动端的项目开发中,总的来说,该框架用起来也挺灵活的,控件可以自由定制,前提是自己能认真地学习该框架的api,因为api里面说的东西比较详细,如果没有仔细看的,可能有些 ...

  2. python之三元表达式,列表|字典推导式,函数对象

    #### 三元表达式: 就是if....else...的语法糖 # -- 1) 只能解决if...else...结构,其他if分支结构都不管 # -- 2)一个分支提供一个结果: 如果一个分支提供了多 ...

  3. Web架构之Nginx基础配置

    目录 1.Nginx 虚拟主机 1.1.基于域名的虚拟主机 1.2.基于端口的虚拟主机 1.3.基于IP的虚拟主机 2.Nginx include 3.Nginx 日志配置 3.1.访问日志 3.2. ...

  4. chrome安装扩展插件出现-crx_header_invalid问题

    1. 将*.crx文件重命名为*.rar 2.将rar文件解压 3. 在chrome浏览器添加扩展程序时选择“加载已解压的扩展程序” 4.添加成功

  5. oracle12c数据库第一周小测验

    一.单选题(共4题,30.4分) 1 (  )是位于用户与操作系统之间的一层数据管理软件.数据库在建立.使用和维护时由其统一管理.统一控制.   A. A.DBMS B. B.DB C. C.DBS ...

  6. C++ 判断两个圆是否有交集

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <math.h> #include <easyx.h ...

  7. js 数组一些简单应用

    把两个数组连接成按从小到大的一个数组例如: var allowVlan = '23-25,45,4-6,67,50-53'; var unTagVlan = '1-5'; 完成时应该是1-6,23-2 ...

  8. 关于WPF System.windows.Media.FontFamily 的类型初始值设定项引发异常问题解决方法

    造成原因:此问题的根本原因是.NET Framework January 2018 Rollup(KB4055002)与已安装的.NET Framework 4.7.1产品版本之间的MSI安装交互.R ...

  9. C++ 人脸识别系统的浅理解

    机器学习 机器学习的目的是把数据转换成信息. 机器学习通过从数据里提取规则或模式来把数据转成信息. 人脸识别 人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸. 每个节点的正确识别率很高,但正确 ...

  10. Natas10 Writeup(正则表达式、grep命令)

    Natas10: 页面与上一关类似,只是增加了提示“出于安全原因,我们现在过滤某些字符”. 查看源码,发现关键代码如下: $key = ""; if(array_key_exist ...