最近没有更新博客,全是因为英语,英语太难了QWQ

洛谷春令营的作业我也不会(我是弱鸡),随机跳了2个题,难度不高,还是讲讲吧,学学新算法也好(可以拿来水博客)

第一题就是这个小明的游戏

小明最近喜欢玩一个游戏。给定一个 n×m的棋盘,上面有两种格子#和@。游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。如果移动到同一类型的格子,则费用是0,否则费用是1。请编程计算从起始位置移动到目标位置的最小花费。

输入格式

输入文件有多组数据。
输入第一行包含两个整数n,m,分别表示棋盘的行数和列数。
输入接下来的n行,每一行有m个格子(使用#或者@表示)。
输入接下来一行有四个整数x1, y1, x2, y2
分别为起始位置和目标位置。
当输入n,m均为0时,表示输入结束。 输出格式 对于每组数据,输出从起始位置到目标位置的最小花费。每一组数据独占一行。

看起来像个广搜,但是我们仔细想想的话会发现,这玩意是有权值的,可能我走100格用的费用比你走一格用的都少,在最少费用的要求下,显然不能用普通的广搜。

广搜的特点是把所有能走到的点全加进队列,为什么会用这种算法呢?,因为每走一步就需要一点费用的情况下,这样走花费最少。

于是,我们可以想出一个主意,我们让队列双开口,把花费小的放在前面,花费大的放后面岂不美哉。但有的同学可能会疑惑(其实只有我),这样的话不是要手打堆排?不不不,里面最多有2种数,因为我们去查看大数的情况前先要看小数的情况,小数只能变成自己或者自己+1,如果是自己+1,变成大数,放在最后。如果不是,放在前面再来一遍。所以这个队列里只会有2种数。不用担心排序的问题。

再来几个小提示就贴代码了:

1、队列记得清空

2、记得标记来过没

3、有个东西叫deque,deque支持高效插入和删除容器的头部和尾部元素,因此也叫做双端队列(我用的就是这个)

#include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
char sz[505][505];
long long a[500][500];
long long n,m,qx,qy,zx,zy;
long long fx[4]={0,0,1,-1};//控制移动的数组
long long fy[4]={1,-1,0,0};
deque<int>qz;//3个双端队列
deque<int>xd;
deque<int>yd;
long long x,y,z;
void sddl()
{
while(xd.empty()!=true&&yd.empty()!=true)//不空不走
{
x=xd.front();//这个是获取队列的头部元素
y=yd.front();
z=qz.front();
if(x==zx&&y==zy)
{
while (xd.empty()!=true)xd.pop_front();//清空队列,我之前因为没清空疯狂80分
while (yd.empty()!=true)yd.pop_front();
while (qz.empty()!=true)qz.pop_front();
cout<<z<<endl;
return;
}
xd.pop_front();
yd.pop_front();
qz.pop_front();
for(int i=0;i<4;i++)
{
if(x+fx[i]>=0&&x+fx[i]<n&&y+fy[i]>=0&&y+fy[i]<m)//判断越界
{
if(a[x+fx[i]][y+fy[i]]==0)//标记来过没
{
a[x+fx[i]][y+fy[i]]=1;
if(sz[x+fx[i]][y+fy[i]]==sz[x][y])//走这个不需要花费,走起
{
xd.push_front(x+fx[i]);//这个是插入到头部的意思
yd.push_front(y+fy[i]);
qz.push_front(z);
}else//花费1点
{
xd.push_back(x+fx[i]);//这个是插入到尾部的意思
yd.push_back(y+fy[i]);
qz.push_back(z+1);
}
}
}
}
}
return;
}
int main()
{
while(true)
{
scanf("%lld%lld",&n,&m);
if(n==0&&m==0)
{
return 0;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>sz[i][j];
a[i][j]=0;
}
}
scanf("%lld%lld%lld%lld",&qx,&qy,&zx,&zy);
a[qx][qy]=1;//省一下
xd.push_front(qx);//这个是插入到头部的意思
yd.push_front(qy);
qz.push_front(0);
sddl();
}
return 0;
}

阳光健康,就到这里吧。

P4554 小明的游戏 (洛谷) 双端队列BFS的更多相关文章

  1. CH 2601 - 电路维修 - [双端队列BFS]

    题目链接:传送门 描述 Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上.Rika的家里有一辆飞行车.有一天飞行车的电路板突然出现了故障,导致 ...

  2. CH2601 电路维修(双端队列bfs)建图恶心

    CH2601 电路维修 双端队列bfs,其实就是因为只有0和1所以可以直接2维护队列单调性(和优先队列一个道理) 建图的过程需要仔细斟酌(想一想id为什么这么写) 还有,空间要开够(很玄学),我一开始 ...

  3. Luogu P2243 电路维修 双端队列BFS

    当转移的代价是0和一个分明不同的权值时,可以用双端队列BFS去跑(你跑最短路也没问题..QWQ) 而对于这道题,边旋转代价是1,不旋转代价是0:可以直接建图最短路,也可以跑BFS 这个题建图很有意思: ...

  4. codeforces 1064D 双端队列BFS

    双端队列BFS解决的就是路径权值可能为0的图最短路问题,权值为0插入队头,否则插入队尾. 对于这个题,可以看作上下移动的路径的权值为0,左右移动权值为1,而且不能超过规定的步数. 直接广搜求覆盖的点的 ...

  5. 电路维修 (广搜变形-双端队列bfs)

    # 2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On [题目描述] 有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会 ...

  6. 2601 电路维修 (双端队列bfs\优先队列bfs(最短路))

    描述 Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上.Rika的家里有一辆飞行车.有一天飞行车的电路板突然出现了故障,导致无法启动. 电路板 ...

  7. POJ 3662 Telephone Lines【二分答案+最短路】||【双端队列BFS】

    <题目链接> 题目大意: 在一个节点标号为1~n的无向图中,求出一条1~n的路径,使得路径上的第K+1条边的边权最小. 解题分析:直接考虑情况比较多,所以我们采用二分答案,先二分枚举第K+ ...

  8. HDU - 6386 Age of Moyu (双端队列+bfs)

    题目链接 双端队列跑边,颜色相同的边之间的花费为0,放进队首:不同的花费为1,放进队尾. 用Dijkstra+常数优化也能过 #include<bits/stdc++.h> using n ...

  9. P4554 小明的游戏

    SPFA板子题 #include <stdio.h> #include <string.h> #define Clean(X,K) memset(X,K,sizeof(X)) ...

随机推荐

  1. 基于flask的城市空气质量分析系统

    1.1  系统功能 在对主要需求进行分析后,确定系统由以下几个模块组成. 1) 用户信息管理: 该部分主要完成系统管理员的增加.删除.编辑和访问控制权限等操作. 2) 数据管理: 该部分主要完成后台存 ...

  2. 003.OpenShift网络

    一 OpenShift网络实现 1.1 软件定义网络(SDN) 默认情况下,Docker网络使用仅使用主机虚机网桥bridge,主机内的所有容器都连接至该网桥.连接到此桥的所有容器都可以彼此通信,但不 ...

  3. docsify 如何写博客

    1. 安装node 下载安装即可: https://nodejs.org/zh-cn/ 下载文件: https://nodejs.org/dist/v12.16.1/node-v12.16.1-x64 ...

  4. ES7.x客户端的认证创建一步一步来

    前言 好久没来写博客了,还是简单的记录一下吧.今天要写的是es在7.x版本后的客户端的创建以及一些es的查询所语句到的小问题.直接先吧客户端端的代码呈上. 正文 public class ESClie ...

  5. 在Ubuntu上实现人脸识别登录

    安装Howdy: howdy项目地址 sudo add-apt-repository ppa:boltgolt/howdy sudo apt update sudo apt install howdy ...

  6. 《HelloGitHub》第 51 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  7. Python实用笔记——错误处理

    让我们用一个例子来看看try的机制: try: print('try...') r = 10 / 0 print('result:', r) except ZeroDivisionError as e ...

  8. Layui的省市区三级联动

    PHP: /** * 通过接口获取省市区 * @param string $name * @return json */ public function getDataTree($name = '') ...

  9. less的使用几个技巧

    1.层级关系 让这个box范围内的全部包进来,这样的话就完美的进行调节,再也不用到处找第几行第几个,我刚才在哪个位置给覆盖了.一看便知! .box{ width: 100%; height: 300p ...

  10. Zip破解工具Fcrackzip使用简介

    0x00 fcrackzip简单介绍 fcrackzip是一款专门破解zip类型压缩文件密码的工具,工具小巧方便.破解速度快,能使用字典和指定字符集破解,适用于linux.mac osx 系统 0x0 ...