HZOJ 走格子
作者的正解:
对于100%的数据:行动可以分为两种:
1. 步行,花费一个单位的时间移动到4联通的相邻格子中去.
2. 使用传送门,指定一个方向的墙的前面的一个格子,步行至最近的一个墙的面前,使用传送门传送.花费的时间为到达最近墙面前花费的时间+1.
两种行动相组合即可组成任意行动过程.那BFS求出最近的墙的距离,预处理上下左右的第一面墙前的格子.然后建图用DJ跑最短路即可.复杂度为O(MNlog(NM))。
其实所的很清楚了,只是不知道bfs是个什么玩意……直接$n^3$暴扫就行了呀。倒真的没什么可说的,看代码吧。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define MP(a,b) make_pair(a,b)
#define ma(x,y) memset(x,y,sizeof(x))
#define LL long long
#define INF 1000000
using namespace std;
struct edge
{
int u,v,w,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define w(x) ed[x].w
#define n(x) ed[x].nxt
}ed[];
int first[],num_e;
#define f(x) first[x]
char map[][];
int up[][],un[][];
int le[][],re[][];
int n,m;
int cx,cy,fx,fy;
inline int get(int i,int j){return (i-)*m+j;}
inline pair<int,int> ret(int val){return MP(val/m+,val%m);}
int dis[];
bool v[];
void dist(int st)
{
ma(dis,0x7f);
priority_queue<pair<int,int> >q;
dis[st]=;q.push(MP(,st));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(v[x])continue;v[x]=;
for(int i=f(x);i;i=n(i))
if(dis[x]+w(i)<dis[v(i)])
dis[v(i)]=dis[x]+w(i),
q.push(MP(-dis[v(i)],v(i)));
}
}
inline void add(int u,int v,int w);
signed main()
{
cin>>n>>m;
for(int i=;i<=n;i++)
scanf("%s",map[i]+);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(map[i][j]=='C')cx=i,cy=j;
if(map[i][j]=='F')fx=i,fy=j;
if(map[i][j]=='#')
up[i][j]=un[i][j]=le[i][j]=re[i][j]=INF;
else
{
for(int k=i-;k>;k--)//上
if(map[k][j]=='#'){up[i][j]=k+;break;}
for(int k=i+;k<=n;k++)//下
if(map[k][j]=='#'){un[i][j]=k-;break;}
for(int k=j-;k>;k--)//左
if(map[i][k]=='#'){le[i][j]=k+;break;}
for(int k=j+;k<=m;k++)//右
if(map[i][k]=='#'){re[i][j]=k-;break;}
}
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(map[i][j]!='#')
{
if(map[i-][j]!='#')add(get(i,j),get(i-,j),);//,add(get(i-1,j),get(i,j),1);//上
if(map[i+][j]!='#')add(get(i,j),get(i+,j),);//,add(get(i+1,j),get(i,j),1);//下
if(map[i][j-]!='#')add(get(i,j),get(i,j-),);//,add(get(i,j-1),get(i,j),1);//左
if(map[i][j+]!='#')add(get(i,j),get(i,j+),);//,add(get(i,j+1),get(i,j),1);//右
//上
{
add(get(i,j),get(un[i][j],j),i-up[i][j]+);//下
add(get(i,j),get(i,le[i][j]),i-up[i][j]+);//左
add(get(i,j),get(i,re[i][j]),i-up[i][j]+);//右
}
//下
{
add(get(i,j),get(up[i][j],j),un[i][j]-i+);//上
add(get(i,j),get(i,le[i][j]),un[i][j]-i+);//左
add(get(i,j),get(i,re[i][j]),un[i][j]-i+);//右
}
//左
{
add(get(i,j),get(up[i][j],j),j-le[i][j]+);//上
add(get(i,j),get(un[i][j],j),j-le[i][j]+);//下
add(get(i,j),get(i,re[i][j]),j-le[i][j]+);//右
}
//右
{
add(get(i,j),get(up[i][j],j),re[i][j]-j+);//上
add(get(i,j),get(un[i][j],j),re[i][j]-j+);//下
add(get(i,j),get(i,le[i][j]),re[i][j]-j+);//左
}
}
dist(get(cx,cy));
printf("%d\n",dis[get(fx,fy)]);
}
inline void add(int u,int v,int w)
{
if(u==v)return;
++num_e;
u(num_e)=u;
v(num_e)=v;
w(num_e)=w;
n(num_e)=f(u);
f(u)=num_e;
}
HZOJ 走格子的更多相关文章
- 51nod1486 大大走格子
容斥定理+dp...妈呀#1rp耗尽了难怪最近那么衰... #include<cstdio> #include<cstring> #include<cctype> ...
- 1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏
1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右 ...
- 51nod 1486 大大走格子(容斥原理)
1486 大大走格子 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有一个h行w列的棋盘,里面有一些格子是不能走的,现在要 ...
- 51Nod 1344 走格子
参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6445381.html 1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: ...
- 51Nod 1344 走格子(贪心
1344 走格子 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i ...
- 【51NOD】1486 大大走格子
[算法]动态规划+组合数学 [题意]有一个h行w列的棋盘,定义一些格子为不能走的黑点,现在要求从左上角走到右下角的方案数. [题解] 大概能考虑到离散化黑点后,中间的空格子直接用组合数计算. 然后解决 ...
- 51nod 1344 走格子【贪心/前缀和】
1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格 ...
- 51Nod 1486 大大走格子 —— 组合数学
题目链接:https://vjudge.net/problem/51Nod-1486 1486 大大走格子 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: ...
- 51nod1344 走格子
1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格 ...
随机推荐
- SQL SERVER 自增列的方法
declare @Table_name varchar(60) set @Table_name = ''; if Exists(Select top 1 1 from sysobjects ...
- CenOS SSH无密码登录
系统环境:CentOS6.8 软件环境:SSH(yum -y install openssh-clients) IP 地址:192.168.0.188 用户环境:root.xiaoming 系统 ...
- Javascript-正则表达式常用字符集及方法
正则表达式修饰符(修饰符 可以在全局搜索中不区分大小写) i(ignoreCase)执行对大小写不敏感的匹配 g (global) 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) m( ...
- 访问Bing地图
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- GDOI2017第四轮day1总结
总的来说这场比赛,只能说是勉强正常发挥. 实在是知识水平有限,最后没能突破瓶颈. 有几个做得好的地方: 1.想好了在写题: 2.暴力也会拍 3.适当地放弃题. 要学习的东西: 1.Sg,线性基: 2. ...
- web标准中定义id与class有什么区别吗
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/x ...
- 使用mpvue开发github小程序总结
前言 最近有点闲,想起关注已久的mpvue写小程序,所以稍微肝了半个多月写了个github版的微信小程序,已上线.现在总结一下遇到的坑. 扫码体验. 项目地址.https://github.com/c ...
- 写GULP遇到的ES6问题详解
Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务.最近复习一下gulp一些基本的写法,在写了一些简单的uglify,rename,concat,clean的处理之 ...
- git gc干了啥
前几天在写升级项目的时候发现./git/objects/pack/下的idx和pack文件是只读的,用java在windows下删除会抛异常,然后把只读属性改掉就好了. 于是就想弄清楚这两个文件的作用 ...
- matplotlib常用操作
1.根据坐标点绘制: import numpy as np import matplotlib.pyplot as plt x = np.array([1,2,3,4,5,6,7,8]) y = np ...