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号格 ...
随机推荐
- python 显示彩色文本
实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用 ...
- Bootstrap启动(关闭)轮播
$('.carousel').carousel(); //启动轮播 $('.carousel').carousel(‘pause’); //关闭轮播 $(‘.carousel’).carousel({ ...
- tumblr arch information
http://developer.51cto.com/art/201305/395757.htm 每月超过30%的增长当然不可能没有挑战,其中可靠性问题尤为艰巨.每天5亿次浏览量,峰值每秒4万次请求, ...
- 关于memset的使用
有些oj上的G++支持 cstdio的memset,有些则支持stdio.h中的memset(划掉) 这两个头文件关系比较复杂, 具体我也说不清...按照c++文档中的说法,stdio已经deprec ...
- 关于Vector CANoe的讨论
默认排序 踩猫尾巴 汽车电子攻城狮 27 人赞同了该回答 好像是很久以前的问题啊,为什么会现在收到邀请. 我觉得 @lijuqqkiko 介绍的足够啦. 我再额外发散一点吧. 目前在CAN总线测试和 ...
- LUOGU P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
传送门 解题思路 记忆化搜索,如果搜到环,就将环的大小处理出来. 代码 #include<iostream> #include<cstdio> #include<cstr ...
- go struct 继承
- WPF Popup实现拖动
问题一.popup总是置顶,遮挡其他窗口 最近发现popup设置打开后,总是会遮挡其他窗口,而我们只想让它仅仅在应用程序的上一层即可,并不像让它在最上面 解决方案是继承Popup重新定义控件Popup ...
- Leetcode917.Reverse Only Letters仅仅反转字母
给定一个字符串 S,返回 "反转后的" 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转. 示例 1: 输入:"ab-cd" 输出:" ...
- 【水滴石穿】react-native-ble-demo
项目的话,是想打开蓝牙,然后连接设备 点击已经连接的设备,我们会看到一些设备 不过我这边在开启蓝牙的时候报错了 先放作者的项目地址: https://github.com/hezhii/react-n ...