\(\\\)

\(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的更多相关文章

  1. [Codeforces Round #516][Codeforces 1063B/1064D. Labyrinth]

    题目链接:1063B - Labyrinth/1064D - Labyrinth 题目大意:给定一个\(n\times m\)的图,有若干个点不能走,上下走无限制,向左和向右走的次数分别被限制为\(x ...

  2. Codeforces 1064 D - Labyrinth

    D - Labyrinth 对于位置(i,j), j - c = R - L = const(常数), 其中R表示往右走了几步,L表示往左走了几步 所以R越大, L就越大, R越小, L就越小, 所以 ...

  3. CodeForces 616C The Labyrinth

    先预处理出所有连通块,对于每一个*,看他四周的连通块即可 #include<cstdio> #include<cstring> #include<queue> #i ...

  4. Codeforces 1064D/1063B Labyrinth

    原题链接/原题链接(代理站) 题目翻译 给你一个\(n*m\)的迷宫和起始点,有障碍的地方不能走,同时最多向左走\(x\)次,向右走\(y\)次,向上向下没有限制,问你有多少个格子是可以到达的. 输入 ...

  5. [ CodeForces 1063 A ] Oh Those Palindromes

    \(\\\) \(Description\) 给出 \(N\) 个小写字母,将他们排成一个字符串,使得这个字符串里包含的回文串最多. \(N\le 10^5\) \(\\\) \(Solution\) ...

  6. 【Codeforces 1063B】Labyrinth

    [链接] 我是链接,点我呀:) [题意] 你可以往左最多x次,往右最多y次 问你从x,y出发最多能到达多少个格子 只能往上下左右四个方向走到没有障碍的格子 [题解] 假设我们从(r,c)出发想要到固定 ...

  7. 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 ...

  8. 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 ...

  9. Codeforces Round #516 (Div. 2)D. Labyrinth

    D. Labyrinth 题目链接:https://codeforces.com/contest/1064/problem/D 题意: 给出一个n*m的矩阵以及人物的起点,并且给出x,y,分别代表这个 ...

随机推荐

  1. Java内存分配与参数传递

    JAVA中方法的参数传递方式只有一种:值传递. JAVA内存分配: 1.栈:存放 基本类型的数据.对象的引用(类似于C语言中的指针) 2.堆:存放用new产生的数据 3.静态域:存放在对象中用stat ...

  2. Thread.run方法是同步方法

    Thread.run方法是同步方法, 线程: package com.stono.thread.page005; public class MyThread extends Thread { @Ove ...

  3. 魔兽 如何屏蔽F1键弹出帮助菜单

    如下图所示,我在任何时候按F1键,都会自动弹出Windows帮助和支持,事实上这个功能很鸡肋,从来没用过,但是玩魔兽的时候确实必须的,F1控制英雄的,呵呵.   方法还是有的,在任务管理器中找到这个应 ...

  4. 深度学习-theano-windows -cuda-环境搭建

    本文将具体介绍深度学习之cuda的环境搭建 工具:支持CUDA的显卡(安装cuda6.5),VS2013.Anaconda. 步骤: 1.安装cuda6.5 这个不具体介绍,网上有很多文章.注意选择你 ...

  5. ie 代理设置中地址和端口置灰的解决办法

    @echo offecho 代理设置reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings&quo ...

  6. c#如何设置成:【当前打开的项目是什么,就默认它为启动项目】,不然新添或打开别的项目都要设置一次启动 [原创]VS2012中将当前选定项目做为启动项

    主菜单→[工具]→[选项]→[项目和解决方案]→[生成并运行],选中“对于新解决方案,使用当前选定的项目作为启动项目” 应该是右键单击解决方案,点击属性打开,选中“当前选定内容”那一项,就可以把你正在 ...

  7. 动态生成页面(一)——ASP.NET中Literal使用

    在页面中加入内容时,假设是静态内容.无需使用容器,能够直接将标记作为HTML直接加入到页面中:可是,假设是动态内容,则必须借助容器将内容加入到页面中.典型的容器有:Label控件.Literal控件. ...

  8. 剑指Offer面试题29(java版):数组中出现次数超过一半的数字

    题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 比如输入一个长度为9的数组{1,2,3,2.2,2.5,4,2}.因为数字2在数组中出现5次,超过数组长度的一半,因此输出2. 解 ...

  9. ibatis 取消查询动态列的缓存

    ibatis在查询结果列不确定(或是动态变化)的情况下,会因为列缓存的原因导致变化后的列数据查不出来 解决方法是: select标签有个属性remapResults,该属性默认值为false,设置成r ...

  10. Sqoop异常解决ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: No columns to generate for ClassWriter问题

    问题详情如下: 解决办法 这个是由于mysql-connector-java的bug造成的,出错时我用的是mysql-connector-java-5.1.10-bin.jar,更新成mysql-co ...