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基础--计算机网络
网络编程: 软件开发架构: c/s架构(client/server) c:客户端 s:服务端 b/s架构(browser/server) b:浏览器 s:服务端 服务端:24小时不间断提供服务 客户端 ...
- IntelliJ IDEA包层级结构显示方式
在开发的过程中,程序结构增多,通过树状结构看包结构目录,更加舒适. Idea默认情况下是不分层级展示包结构的 点击设置标志按钮,如下图所示 去掉Hide Empty Middle Packages的勾 ...
- 发布Qt Widgets桌面应用程序的方法
Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于是我花了一点儿时间介绍一下如何发布Qt桌 ...
- SQL Server删除用户失败的解决方法
在删除SQL Server用户时,有时会报错:Microsoft SQL Server错误: 15138删除对于用户失败,数据库主体在该数据库中拥有架构,无法删除.删除 对于 用户“*****”失败. ...
- Codeforces Round #410 (Div. 2) A. Mike and palindrome【判断能否只修改一个字符使其变成回文串】
A. Mike and palindrome time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- Java.控制层.响应工具类.
Java.控制层.响应工具类. package cn.com.spdbccc.cds.index.web.base; public class ApiResponse { private int co ...
- php rmdir使用递归函数删除非空目录的方法
php rmdir()函数 rmdir ― 删除空目录 语法: bool rmdir ( string $dirname [, resource $context ] )尝试删除 dirname 所指 ...
- 用JS实线放大镜的效果
今天花了点时间,复习了下使用原生JS实线放大镜的效果.在制作过程中,也是很到了一些问题,在这里总结下. HTML代码如下: <div id="preview"> < ...
- ls command not found
编辑profile文件没有写正确,导致在命令行下 ls等命令不能够识别. 在命令行下打入下面这段就可以了 export PATH=/usr/local/sbin:/usr/local/bin:/sbi ...
- KDD2016,Accepted Papers
RESEARCH TRACK PAPERS - ORAL Title & Authors NetCycle: Collective Evolution Inference in Heterog ...