[ CodeForces 1063 B ] Labyrinth
\(\\\)
\(Description\)
给出一个四联通的\(N\times M\) 网格图和起点。图中有一些位置是障碍物。
现在上下移动步数不限,向左至多走 \(a\) 步,向右至多走 \(b\) 步,求从起点出发能到达多少个空地。
- \(N,M\le 2000\)
\(\\\)
\(Solution\)
爷们太神了......
开始的想法是直接跑最短路, \(dist\) 为横向移动总步数。
后来发现矛盾在于,如果到一个格子向左走的步数较少,向右走的步数较多,和这种情况反过来,无法确定那种更优,进而无法确定用那种状态更新接下来的点。
然后听爷们讲了好久听懂了正确性证明。考虑要从起点 U 到达 V 这个格子,它横向的差值为 \(2\) 是固定的。
也就是说,任何一个合法的方案向左走的步数减掉向右走的步数都应该等于 \(2\)。
那么这种矛盾不存在了。因为向左向右的步数会同时增长,否则一定不会到达这个目标点。

然后就愉快上最短路,根据\(Dij\) 的原理,循环次数就是访问的点数。
\(\\\)
\(Code\)
#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2010
#define R register
#define gc getchar
#define inf 2000000000
using namespace std;
typedef long long ll;
inline ll rd(){
ll x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}
int n,m,lx,rx,ux,uy,ans;
bool mp[N][N],vis[N][N];
struct dist{
int x,y,l,r,sum;
friend operator < (const dist &x,const dist &y){
return x.sum>y.sum;
}
}dis[N][N];
priority_queue<dist> q;
int main(){
n=rd(); m=rd();
ux=rd(); uy=rd();
lx=rd(); rx=rd();
char c=gc();
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j){
while(c!='.'&&c!='*') c=gc();
mp[i][j]=(c=='.');
c=gc();
dis[i][j].x=i; dis[i][j].y=j;
dis[i][j].l=dis[i][j].r=dis[i][j].sum=inf;
}
dis[ux][uy].l=dis[ux][uy].r=dis[ux][uy].sum=0;
q.push(dis[ux][uy]);
while(!q.empty()){
dist x=q.top(); q.pop();
if(vis[x.x][x.y]) continue;
vis[x.x][x.y]=1; ++ans;
if(mp[x.x+1][x.y]){
if(dis[x.x+1][x.y].sum>x.sum){
dis[x.x+1][x.y].l=x.l;
dis[x.x+1][x.y].r=x.r;
dis[x.x+1][x.y].sum=x.sum;
q.push(dis[x.x+1][x.y]);
}
}
if(mp[x.x-1][x.y]){
if(dis[x.x-1][x.y].sum>x.sum){
dis[x.x-1][x.y].l=x.l;
dis[x.x-1][x.y].r=x.r;
dis[x.x-1][x.y].sum=x.sum;
q.push(dis[x.x-1][x.y]);
}
}
if(mp[x.x][x.y-1]&&x.l<lx){
if(dis[x.x][x.y-1].sum>x.sum+1){
dis[x.x][x.y-1].l=x.l+1;
dis[x.x][x.y-1].r=x.r;
dis[x.x][x.y-1].sum=x.sum+1;
q.push(dis[x.x][x.y-1]);
}
}
if(mp[x.x][x.y+1]&&x.r<rx){
if(dis[x.x][x.y+1].sum>x.sum+1){
dis[x.x][x.y+1].l=x.l;
dis[x.x][x.y+1].r=x.r+1;
dis[x.x][x.y+1].sum=x.sum+1;
q.push(dis[x.x][x.y+1]);
}
}
}
printf("%d\n",ans);
return 0;
}
[ CodeForces 1063 B ] Labyrinth的更多相关文章
- [Codeforces Round #516][Codeforces 1063B/1064D. Labyrinth]
题目链接:1063B - Labyrinth/1064D - Labyrinth 题目大意:给定一个\(n\times m\)的图,有若干个点不能走,上下走无限制,向左和向右走的次数分别被限制为\(x ...
- Codeforces 1064 D - Labyrinth
D - Labyrinth 对于位置(i,j), j - c = R - L = const(常数), 其中R表示往右走了几步,L表示往左走了几步 所以R越大, L就越大, R越小, L就越小, 所以 ...
- CodeForces 616C The Labyrinth
先预处理出所有连通块,对于每一个*,看他四周的连通块即可 #include<cstdio> #include<cstring> #include<queue> #i ...
- Codeforces 1064D/1063B Labyrinth
原题链接/原题链接(代理站) 题目翻译 给你一个\(n*m\)的迷宫和起始点,有障碍的地方不能走,同时最多向左走\(x\)次,向右走\(y\)次,向上向下没有限制,问你有多少个格子是可以到达的. 输入 ...
- [ CodeForces 1063 A ] Oh Those Palindromes
\(\\\) \(Description\) 给出 \(N\) 个小写字母,将他们排成一个字符串,使得这个字符串里包含的回文串最多. \(N\le 10^5\) \(\\\) \(Solution\) ...
- 【Codeforces 1063B】Labyrinth
[链接] 我是链接,点我呀:) [题意] 你可以往左最多x次,往右最多y次 问你从x,y出发最多能到达多少个格子 只能往上下左右四个方向走到没有障碍的格子 [题解] 假设我们从(r,c)出发想要到固定 ...
- Codeforces Educational Codeforces Round 5 C. The Labyrinth 带权并查集
C. The Labyrinth 题目连接: http://www.codeforces.com/contest/616/problem/C Description You are given a r ...
- Codeforces Round #354 (Div. 2) D. Theseus and labyrinth bfs
D. Theseus and labyrinth 题目连接: http://www.codeforces.com/contest/676/problem/D Description Theseus h ...
- Codeforces Round #516 (Div. 2)D. Labyrinth
D. Labyrinth 题目链接:https://codeforces.com/contest/1064/problem/D 题意: 给出一个n*m的矩阵以及人物的起点,并且给出x,y,分别代表这个 ...
随机推荐
- Django学习系列之CSRF
Django CSRF 什么是CSRF CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到 ...
- Redis官网下载步骤(含windows版)
①.百度redis ,进入官网 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- C++进阶之虚函数表
C++通过继承(inheritance)和虚函数(virtual function)来实现多态性.所谓多态,简单地说就是,将基类的指针或引用绑定到子类的实例,然后通过基类的指针或引用调用实际子类的成员 ...
- EJB之JPA
在前一篇文章中大概了解了EJB是什么?那么接下来就进一步介绍一下它与JPA有什么样的关系?及什么是JPA?JPA怎样用? 一.是什么? 第一次听说JPA是在EJB视屏中,所以一直感觉他们有不解的渊源. ...
- rsync 3.1.1源代码编译安装配置
http://rsync.samba.org/ rsync-3.1.1.tar.gz ---0.卸载rpm # yum remove rsync -----1.安装: tar -zxvf rsync- ...
- gdb 调试利器
1. gdb 调试利器 GDB是一个由GNU开源组织公布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调试工具.对于一名Linux下工作的c++程序猿,gdb是不可缺少的工具: 1 ...
- mac终端配置Android ADB命令
不得不说mac是一款开发利器,不仅可以开发ios,而且对于Android开发也是不错的选择,下面我就对mac配置adb命令,进行简要的说明.下面我将一下mac环境下的配置步骤:1.在自己的目录(hom ...
- 6个变态的C语言Hello World程序 之 雷人的程序语言
以下的六个程序片段主要完毕这些事情: 输出Hello, World 混乱C语言的源码 以下的全部程序都能够在GCC下编译通过,仅仅有最后一个须要动用C++的编译器g++才干编程通过. hello1.c ...
- Interfaces (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/ms173156.aspx An interface contains definitions for a group ...
- YTU 2690: 用双重循环实现小九九
2690: 用双重循环实现小九九 时间限制: 1 Sec 内存限制: 128 MB 提交: 848 解决: 573 题目描述 小九九是我们小时候常背的的乘法算术法则,现在用双重循环来实现小九九 1 ...