BZOJ4829: [Hnoi2017]队长快跑

Description

众所周知,在P国外不远处盘踞着巨龙大Y。
传说中,在远古时代,巨龙大Y将P国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个P国的所有冒险家前去夺回,尤其是皇家卫士队的队长小W。
在P国量子科技实验室的帮助下,队长小W通过量子传输进入了巨龙大Y的藏宝室,并成功夺回了镇国之宝。
但此时巨龙布下的攻击性防壁启动,将小W困在了美杜莎的迷宫当中。
被困在迷宫(0,0)处的队长小W快速观察了美杜莎的迷宫的构造,发现迷宫的出口位于(p,q)处。
巨龙大Y在迷宫当中布置了n火焰吐息机关,每个机关可以用三个参数(x,y,θ)表示,分别指明机关位于平面的坐标(x,y),以及火焰吐息的方向相对于x正方向的倾角θ。
巨龙强大的力量使得火焰吐息有无穷长,且队长小W不能通过被火焰吐息覆盖的射线(注意,机关所处的坐标若没有被其他火焰吐息覆盖,则是可以通过的)。
同时,迷宫在沿x负方向无穷远的地方放置了美杜莎之眼,使得队长小W必须倾向于向x正方向行动(即队长小W的移动方向在x正方向上的投影必须为正,不能是负数或零),否则队长小W将被瞬间石化而无法逃离。
心急如焚的队长小W需要趁着巨龙大Y还没将其抓住前逃离美杜莎的迷宫,所以他立马向P国智囊团求助,作为智囊团团长的你,一定可以帮队长小W找出安全逃至迷宫出口的最短道路。

Input

第一行为三个整数n,p,q,分别表示火焰吐息机关总数以及出口坐标。
接下来n行,每行两个整数与一个实数(x,y,θ)分别表示机关所处的坐标以及火焰吐息的关于x正方向的倾角。

Output

输出文件仅包含一行一个小数,表示最短道路的长度。
当你的答案和标准答案的相对误差不超过10^-8时(即|a-o|/a≤10-8时,其中a是标准答案,o是输出)认为你的答案正确。

Sample Input

7 20 -5
4 3 -2.875
5 7 -1.314
10 -2 0.666
16 1 -1.571
16 1 1.571
23 -3 -2.130
14 -5 3.073

Sample Output

33.3380422500
题解Here!

我们可以把射线的方向规约成两类,相对于s,t分成向上与向下的两种。

不难发现,改变射线的方向后,原有的限制条件并未被改变。

要判断一条线是否规约为“垂直向下”,只需判断它的关于P的极角是否在S和T关于P的极角之间。

问题可以转化为多边形两点间最短距离,有经典算法可以解决,但是目前oi界应该不会涉及到吧。

有一个做法可以通过本题的数据,下面介绍它的具体实现。

将所有射线按端点的横坐标排序,依次计算每个端点到S的最短路径上,距离它最近的点nxt。

维护两个队列q1和q2,分别对应上和下两种方向的端点。

初始时在q1和q2中都放入起点坐标。

每次考虑到一个点P(不妨设它是向上的射线),首先看q2的队首到P的连线是否被队列中后一个元素挡住,如果是,则nxt在q2中;否则nxt在q1中。

若nxt在q2中,则不断判断队首是否被后一个挡住,只要被挡住,就向后移动队首的指针,nxt就是最终的队首。

接着,清空q1,并将nxt放入q1中。

若nxt在q1中,则不断判断q1中倒数第二个是否被队尾挡住,只要没被挡住,就向前移动队尾的指针,nxt就是最终的队尾。

最后,无论nxt在哪里,都在q1的末尾加入P。

至于这种做法的正确性,我想了很久都没有想清楚,但也找不到反例说明它是错误的。

所以,也就这样吧。。。

附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define MAXN 1000010
using namespace std;
const double PI=acos(-1);
int n,top=0,head[2],tail[2];
struct Point{
long long x,y;
Point *next;
int direction;
Point operator +(const Point &p)const{return (Point){x+p.x,y+p.y};}
Point operator -(const Point &p)const{return (Point){x-p.x,y-p.y};}
long long operator *(const Point &p)const{return x*p.y-y*p.x;}
bool operator !=(const Point &p)const{return (x!=p.x||y!=p.y);}
bool operator <(const Point &p)const{return x<p.x;}
double dis()const{return sqrt(x*x+y*y);}
}s,t,a[MAXN],b[MAXN],*que[2][MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline bool NotInRange(double div,double x,double y){
if(div>=-PI/2.0&&div<=PI/2.0)return ((x<div||x>PI/2.0)&&(y<div||y>PI/2.0));
else if(div<0)return (x>div&&x<PI/2.0&&y>div&&y<PI/2.0);
else return ((x>div||x<PI/2.0)&&(y>div||y<PI/2.0));
}
void work(){
double ans=0;
head[0]=tail[0]=head[1]=tail[1]=1;
que[0][1]=que[1][1]=&s;
for(int i=1;i<=n;i++){
int x=a[i].direction,y=x^1;
if(head[y]<tail[y]&&((a[i]-*que[y][head[y]])*(*que[y][head[y]+1]-*que[y][head[y]]))*(x==1?1:-1)>=0){
while(head[y]<tail[y]&&((a[i]-*que[y][head[y]])*(*que[y][head[y]+1]-*que[y][head[y]]))*(x==1?1:-1)>=0)head[y]++;
a[i].next=que[y][head[y]];
head[x]=tail[x]=tail[x]+1;
que[x][head[x]]=que[y][head[y]];
}else{
while(head[x]<tail[x]&&((a[i]-*que[x][tail[x]-1])*(*que[x][tail[x]]-*que[x][tail[x]-1]))*(x==1?1:-1)>=0)tail[x]--;
a[i].next=que[x][tail[x]];
}
que[x][++tail[x]]=&a[i];
}
for(Point *now=&a[n],*last;*now!=s;){
last=now;now=now->next;
ans+=(*now-*last).dis();
}
printf("%.10lf\n",ans);
}
void init(){
double u,v,w;
n=read();t.x=read();t.y=read();
s.x=s.y=0;
for(int i=1;i<=n;i++){
a[i].x=read();a[i].y=read();
scanf("%lf",&w);
u=atan2(s.y-a[i].y,s.x-a[i].x);
v=atan2(t.y-a[i].y,t.x-a[i].x);
if(NotInRange(w,u,v))a[i].direction=1;
else a[i].direction=0;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
if(a[i].x<s.x||a[i].x>t.x)continue;
a[++top]=a[i];
}
a[++top]=t;
n=top;
}
int main(){
init();
work();
return 0;
}

BZOJ4829: [Hnoi2017]队长快跑的更多相关文章

  1. [LOJ 2022]「AHOI / HNOI2017」队长快跑

    [LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...

  2. HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解

    题面:https://www.cnblogs.com/Juve/articles/11487699.html 队长快跑: 权值线段树与dp yy的不错 #include<iostream> ...

  3. NOIP模拟14「队长快跑·影魔·抛硬币」

    T1:队长快跑 基本思路:   离散化·DP·数据结构优化DP   这三个我都没想到....气死.   定义状态数组:\(c[i][j]\)表示在i时最小的a值是j时可以摧毁的最多的水晶数.   那么 ...

  4. [CSP-S模拟测试]:队长快跑(DP+离散化+线段树)

    题目背景 传说中,在远古时代,巨龙大$Y$将$P$国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个$P$国的所有冒险家前去夺回,尤其是皇家卫士队的队长小$W$.在$P$国量子科技实验室的帮助下,队长小$ ...

  5. NOIP 模拟 $14\; \text{队长快跑}$

    题解 \(by\;zj\varphi\) 一道很妙的 \(dp\) 题,方程状态不好设置,细节也不少 看到数据范围,直接想离散化 设 \(f_{i,j}\) 表示处理完前 \(i\) 个水晶,其中摧毁 ...

  6. 原创跑酷小游戏《Cube Duck Run》 - - 方块鸭快跑

    自从unity5出来才开始关注unity,业余时间尝试做了个小游戏: <方块鸭快跑> (Cube Duck Run) 像素风,3d视角,色彩明快,有无尽和关卡两种模式. 应用连接: goo ...

  7. 【python游戏编程之旅】第九篇---嗷大喵快跑小游戏开发实例

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 前几期博客我们一起学习了,pygame中的冲突检测技术以及一些常用的数据结构. 这次我们来一起做一个简单的酷 ...

  8. LYK 快跑!(LYK别打我-)(话说LYK是谁)

    LYK 快跑!(run) Time Limit:5000ms Memory Limit:64MB 题目描述 LYK 陷进了一个迷宫! 这个迷宫是网格图形状的. LYK 一开始在(1,1)位置, 出口在 ...

  9. LYK 快跑!(run)

    LYK 快跑!(run)Time Limit:5000ms Memory Limit:64MB[题目描述] LYK 陷进了一个迷宫! 这个迷宫是网格图形状的. LYK 一开始在(1,1)位置, 出口在 ...

随机推荐

  1. Laravel 时间处理

    $info['date'] = $item->created_at->diffForHumans();//友好时间显示 $info['date'] = $item->created_ ...

  2. Eclipse4.4以上版本不能使用easyExplorer,采用OpenExplorer

    如果想在Ecipse里打开目录,一直用easyExplorer,可是现在版本升级了easyExplorer不好使,可以用OpenExplorer到https://github.com/samsonw/ ...

  3. 深入浅出 Cocoa 之 Core Data(2)- 手动编写代码

    深入浅出 Cocoa 之 Core Data(2)- 代码示例 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 前面详细讲解了 Core Data 的框 ...

  4. Android Studio +MAT 分析内存泄漏实战

    对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的. 首先什么是内存泄漏? 内存泄漏就是一些已经不使用的对 ...

  5. TRIZ系列-创新原理-20-有效作用的连续性原理

    有效作用的连续性原理表述例如以下:1)连续实施动作不要中断,物体的全部部分应该一直处于满负荷工作状态.2)去除全部空暇的,中间的动作:3)用循环的动作取代"来来回回"的动作: 这个 ...

  6. 获取安装后Apache、MySQL、Nginx、PHP编译时参数

    # cat /usr/local/apache2/build/config.nice      //获取Apache编译时的参数 #!/bin/sh # #Created by configure & ...

  7. node.js(一)- 安装配置

    最近在学习node,文章作为记录 一.下载 直接下载最新的包:https://nodejs.org/en/download/ 我这里是自己做开发,所以直接使用的是window 64位的最新v4.5.0 ...

  8. 【音乐App】—— Vue-music 项目学习笔记:歌手页面开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 一.歌手页面布局与设计 需 ...

  9. windows搭建json-server快速方法

    JSON-Server 是一个 Node 模块,运行 Express 服务器,你可以指定一个 json 文件作为 api 的数据源. 一.下载并安装node.js 安装完后输入 node --vers ...

  10. iOS后台解析

    iOS后台 上个月给小妹买了一台6s 她问我双击 Home 键之后 弹出的那些应用会不会耗电 我找到一篇文章 正好说的就是这个问题 摘要翻译一下 原文地址 http://www.speirs.org/ ...