P4554 小明的游戏 (洛谷) 双端队列BFS
最近没有更新博客,全是因为英语,英语太难了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的更多相关文章
- CH 2601 - 电路维修 - [双端队列BFS]
题目链接:传送门 描述 Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上.Rika的家里有一辆飞行车.有一天飞行车的电路板突然出现了故障,导致 ...
- CH2601 电路维修(双端队列bfs)建图恶心
CH2601 电路维修 双端队列bfs,其实就是因为只有0和1所以可以直接2维护队列单调性(和优先队列一个道理) 建图的过程需要仔细斟酌(想一想id为什么这么写) 还有,空间要开够(很玄学),我一开始 ...
- Luogu P2243 电路维修 双端队列BFS
当转移的代价是0和一个分明不同的权值时,可以用双端队列BFS去跑(你跑最短路也没问题..QWQ) 而对于这道题,边旋转代价是1,不旋转代价是0:可以直接建图最短路,也可以跑BFS 这个题建图很有意思: ...
- codeforces 1064D 双端队列BFS
双端队列BFS解决的就是路径权值可能为0的图最短路问题,权值为0插入队头,否则插入队尾. 对于这个题,可以看作上下移动的路径的权值为0,左右移动权值为1,而且不能超过规定的步数. 直接广搜求覆盖的点的 ...
- 电路维修 (广搜变形-双端队列bfs)
# 2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On [题目描述] 有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会 ...
- 2601 电路维修 (双端队列bfs\优先队列bfs(最短路))
描述 Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上.Rika的家里有一辆飞行车.有一天飞行车的电路板突然出现了故障,导致无法启动. 电路板 ...
- POJ 3662 Telephone Lines【二分答案+最短路】||【双端队列BFS】
<题目链接> 题目大意: 在一个节点标号为1~n的无向图中,求出一条1~n的路径,使得路径上的第K+1条边的边权最小. 解题分析:直接考虑情况比较多,所以我们采用二分答案,先二分枚举第K+ ...
- HDU - 6386 Age of Moyu (双端队列+bfs)
题目链接 双端队列跑边,颜色相同的边之间的花费为0,放进队首:不同的花费为1,放进队尾. 用Dijkstra+常数优化也能过 #include<bits/stdc++.h> using n ...
- P4554 小明的游戏
SPFA板子题 #include <stdio.h> #include <string.h> #define Clean(X,K) memset(X,K,sizeof(X)) ...
随机推荐
- C++核心编程
C++核心编程 本阶段主要针对C++面向对象编程技术做详细讲解,探讨C++中的核心和精髓. 1 内存分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统 ...
- Python学习日志-02
(2)Python如何运行程序 Python解释器简介: Python不仅仅是一门编程语言,它也是一个名为解释器的软件包.解释器是一种让其他程序运行起来的程序.当你编写了一段Python程序,Pyth ...
- ORA-12514:监听程序无法识别
使用plsql远程登录oracle数据库时,出现无法识别监听程序的错误.很大机率是配置文件出错. 配置文件如下: listener.ora是服务器端用的,oracle监听程序,就是读的这个文件,里面有 ...
- 006.OpenShift持久性存储
一 持久存储 1.1 持久存储概述 默认情况下,运行容器使用容器内的临时存储.Pods由一个或多个容器组成,这些容器一起部署,共享相同的存储和其他资源,可以在任何时候创建.启动.停止或销毁.使用临时存 ...
- 浅析Java中Ant的使用
Ant是一种基于Java的打包工具,Ant脚本采用XML格式编写,默认的文件名为build.xml. Ant中常用的节点元素 Project Project是项目工程的顶级节点,一个build. ...
- JavaWeb网上图书商城完整项目--day02-26.查询所有分类功能之DAO层实现
我们按照表示的设计 以及: package com.weiyuan.goods.category.domain; import java.util.List; public class Categor ...
- 删库吧,Bug浪——我们在同一家摸鱼的公司
那些口口声声, Bug越来越难写人的,应该盯着你们: 像我一样,我盯着你们,满眼恨意. IT积攒了几十年的漏洞, 所有的死机.溢出.404和超时, 像是专门为你们准备的礼物. 圈复杂度.魔鬼变量.内存 ...
- vueX基础知识笔记
接着昨天的知识点 mutations提交时,有时候达不到想要的响应式,我们必须要将数据提前放到state中,否则不会达到响应式的效果.比如 state.info['address'] = value ...
- 进度条的使用 Progress控件
MFC编程实例二:进度条的使用 2011-03-22 09:09:09| 分类: C++(C语言) | 标签:进度 nlower nupper 添加 mfc |字号 订阅 本人用的 ...
- ORACLE数据库数据被修改或者删除恢复数据(闪回)
1. SELECT * FROM CT_FIN_RiskItem --先查询表,确定数据的确不对 (cfstatus 第一行缺少) 2. select * from CT_FIN_RiskItem ...