【极值问题】【CF1063B】 Labyrinth
Description
给你一个\(n~\times~m\)的矩阵,一开始你在第\(r\)行第\(c\)列。你的上下移动不受限制,向左最多移动\(x\)次,向右最多移动\(y\)次。求你最多能到多少个点。包括起始点。
Input
第一行是\(n\)和\(m\),代表矩阵规模。
第二行是\(r\)和\(c\),代表你的位置
第三行是\(x\)和\(y\),代表移动限制
下面\(n\)行每行\(m\)个字符,有且仅有'.'和''两种。如果第\(i\)行第\(j\)列是''代表你不能经过这个点。
Output
输出一行一个数代表能到的最多点数
Sample Input
4 5
3 2
1 2
.....
.***.
...**
*....
Sample Output
10
Hint
\(For~All:\)
\(0~\leq~n,m,r,c~\leq~2000\),\(0~\leq~x,y~\leq~10^9\)
Solution
朴素的\(bfs\)显然是对的,可以状态太多存不下。
考虑如果从\((sx,sy)\)点到一个点\((x,y)\)时,假设共向右走了\(r\)步,向左走了\(l\)步,显然\(r-l\)是一个定值。具体的,\(r-l~=~y-sy\)。于是,对于任意一个目标\((x,y)\),发现\(l\)事实上与\(r\)线性正相关。对于一个点,显然到该点的\(r\)越小越好,同时由于\(l\)和\(r\)线性正相关,所以最小化\(r\)的同时,\(l\)已经被最小化了。于是可以直接建图跑最短路,所有向右的边权为1,其他边权为0。跑完后扫描整个地图就可以判断合法性了。
这里的一个新姿势是\(0/1bfs\)。当边权只有\(0/1\)时,可以使用双端队列进行bfs,具体的,当当前边的权值时\(0\)时,将终点压入队首,否则压入队尾。考虑这么做的正确性:易证任意一时刻队列中的点dist差值不超过1。于是正确性显然。\(0/1bfs\)的复杂度为\(O(V+E)\)。相比dij少了一个log。
Code
#include<queue>
#include<cstdio>
#include<cstring>
#define rg register
#define ci const int
#define cl const long long int
typedef long long int ll;
namespace IO{
char buf[110];
}
template <typename T>
inline void qr(T &x) {
rg char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
}
template <typename T>
inline void qw(T x,const char aft,const bool pt) {
if(x < 0) {putchar('-');x=-x;}
rg int top=0;
do {
IO::buf[++top]=x%10+'0';
} while(x/=10);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}
template <typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template <typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template <typename T>
inline T mabs(const T a) {return a < 0 ? -a : a;}
template <typename T>
inline void mswap(T &a,T &b) {
T _temp=a;a=b;b=_temp;
}
const int maxn = 2010;
const int fx[]={0,-1,0,1};
const int fy[]={1,0,-1,0};
const int fv[]={1,0,0,0};
int n,m,sx,sy,x,y;
int MU[maxn][maxn];
char mp[maxn][maxn];
std::deque<int>Qx,Qy;
int main() {
qr(n);qr(m);qr(sx);qr(sy);qr(x);qr(y);
for(rg int i=1;i<=n;++i) scanf("%s",mp[i]+1);
memset(MU,0x3f,sizeof MU);
MU[sx][sy]=0; Qx.push_front(sx);Qy.push_front(sy);
while(!Qx.empty()) {
int hx=Qx.front(),hy=Qy.front();Qx.pop_front();Qy.pop_front();
for(rg int i=0;i<4;++i) {
int dx=hx+fx[i],dy=hy+fy[i];
if((dx > n) || (dy > m) || (!dx) || (!dy) || (mp[dx][dy] == '*') || (MU[dx][dy] <= MU[hx][hy]+fv[i])) continue;
MU[dx][dy]=MU[hx][hy]+fv[i];
if(i) {Qx.push_front(dx);Qy.push_front(dy);}
else {Qx.push_back(dx);Qy.push_back(dy);}
}
}
rg int _ans=0;
for(rg int i=1;i<=n;++i) {
for(rg int j=1;j<=m;++j) if(mp[i][j] != '*') {
if((MU[i][j] <= y) && ((MU[i][j]-j+sy) <= x)) ++_ans;
}
}
qw(_ans,'\n',true);
return 0;
}
Summary
当题设需要最小化多个变量时,不妨考虑变量间的相关关系,从此转化成单变量的极值问题。
当边权只有\(0\)和\(1\)的时候,可以考虑使用\(0/1bfs\),省去dij的log。
【极值问题】【CF1063B】 Labyrinth的更多相关文章
- cf1063B Labyrinth (bfs)
可以证明,如果我搜索的话,一个点最多只有两个最优状态:向左剩余步数最大时和向右剩余步数最大时 然后判一判,bfs就好了 dfs会T惨... #include<bits/stdc++.h> ...
- CF1063B Labyrinth
大家一起膜Rorshach. 一般的$bfs$会造成有一些点访问不到的情况,在$system\ test$的时候会$WA40$(比如我……). 发现这张地图其实是一个边权只有$0/1$的图,我们需要计 ...
- $CF1063B\ Labyrinth$ $01$最短路/$01BFS$
\(Des\) 有一个网格图,上面的格子分为空地和障碍,障碍是不可以走的.现在从给定的起点出发开始到处乱走,最多可以往左走\(l\)次,往右走\(r\)次.求可能到达的点数. \(Sol\) 如果只限 ...
- 题解 CF1063B 【Labyrinth】
题解 CF1063B [Labyrinth] 完了我发现我做CF的题大部分思路都和别人不一样qwq 这道题其实很水,不至于到紫题 我们只要bfs一下,向四个方向剪下枝,就A了(好像还跑的蛮快?) 是一 ...
- 2014百度之星资格赛 1004:Labyrinth(DP)
Labyrinth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- ural 1145. Rope in the Labyrinth
1145. Rope in the Labyrinth Time limit: 0.5 secondMemory limit: 64 MB A labyrinth with rectangular f ...
- [POJ1383]Labyrinth
[POJ1383]Labyrinth 试题描述 The northern part of the Pyramid contains a very large and complicated labyr ...
- timus 1033 Labyrinth(BFS)
Labyrinth Time limit: 1.0 secondMemory limit: 64 MB Administration of the labyrinth has decided to s ...
- poj 1383 Labyrinth
题目连接 http://poj.org/problem?id=1383 Labyrinth Description The northern part of the Pyramid contains ...
随机推荐
- Qt-QML-C++交互实现文件IO系统-后继-具体文件IO的实现
在上一篇文章中,我大致将这个QML中的文件IO类搭出了大致的框架,那么,今天抽时间写了一点文件的读写,这里我使用的文件流来读写文件. 文件结构如图 在QML中调用这个类了,就见简单的读取了一个JSON ...
- Qt 解析EXcel文件
写代码需要将excel中的文件导入到数据库中 网上找到以为大神写的,但是当初没有保存,也没有找到 我几乎是原分不动拔下来的,希望大神莫怪 void AddDialog::readExcel(QStri ...
- 前端开发工程师 - 05.产品前端架构 - 协作流程 & 接口设计 & 版本管理 & 技术选型 &开发实践
05.产品前端架构 第1章--协作流程 WEB系统 角色定义 协作流程 职责说明 第2章--接口设计 概述 接口规范 规范应用 本地开发 第3章--版本管理 见 Java开发工程师(Web方向) - ...
- phpanalysis提取关键字
最近在开发一个文章模块功能,设计那边提出要给文章生成对应标签,用于文章关联推送,这里和大家分享一下实现过程: 这里需要用到PHPAnalysis,下载链接如下 链接:https://pan.baidu ...
- GIT: 分布式开发 代码管理工具使用命令大全
代码管理工具: GIT 什么是GIT? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常 ...
- 线性代数之——正交矩阵和 Gram-Schmidt 正交化
这部分我们有两个目标.一是了解正交性是怎么让 \(\hat x\) .\(p\) .\(P\) 的计算变得简单的,这种情况下,\(A^TA\) 将会是一个对角矩阵.二是学会怎么从原始向量中构建出正交向 ...
- OpenCV学习5-----使用Mat合并多张图像
最近做实验需要对比实验结果,需要将几张图片拼在一起,直观对比. 尝试用OpenCV解决. 核心思想其实是 声明一个足够大的,正好容纳下那几张图片的mat,然后将拼图依次copy到大图片相应的位置. ...
- 2017-2018-2 20172314 『Java程序设计』课程 结对编程练习_四则运算
相关过程截图 截图为我负责的部分关于计算的测试 关键代码解释 根据代码中的部分解释,这部分代码实现了结果的整数和分数的输出,如果算出的结果为一个真分数,就输出真分数的形式,如果结果为整数,就输出整数形 ...
- 20162328蔡文琛week02
学号 20162328 <程序设计与数据结构>第2周学习总结 教材学习内容总结 这周学习了课本中的第二章内容,比起第一章,本章难度有略微底稿,从刚开始的显示字符转变为简单的加减乘除运算,经 ...
- 由作业题引发对C++引用的一些思考
首先分析一段代码: #include <bits/c++config.h> #include <ostream> #include <iostream> #incl ...