BZOJ4829: [Hnoi2017]队长快跑
Description
Input
Output
Sample Input
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
我们可以把射线的方向规约成两类,相对于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]队长快跑的更多相关文章
- [LOJ 2022]「AHOI / HNOI2017」队长快跑
[LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...
- HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解
题面:https://www.cnblogs.com/Juve/articles/11487699.html 队长快跑: 权值线段树与dp yy的不错 #include<iostream> ...
- NOIP模拟14「队长快跑·影魔·抛硬币」
T1:队长快跑 基本思路: 离散化·DP·数据结构优化DP 这三个我都没想到....气死. 定义状态数组:\(c[i][j]\)表示在i时最小的a值是j时可以摧毁的最多的水晶数. 那么 ...
- [CSP-S模拟测试]:队长快跑(DP+离散化+线段树)
题目背景 传说中,在远古时代,巨龙大$Y$将$P$国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个$P$国的所有冒险家前去夺回,尤其是皇家卫士队的队长小$W$.在$P$国量子科技实验室的帮助下,队长小$ ...
- NOIP 模拟 $14\; \text{队长快跑}$
题解 \(by\;zj\varphi\) 一道很妙的 \(dp\) 题,方程状态不好设置,细节也不少 看到数据范围,直接想离散化 设 \(f_{i,j}\) 表示处理完前 \(i\) 个水晶,其中摧毁 ...
- 原创跑酷小游戏《Cube Duck Run》 - - 方块鸭快跑
自从unity5出来才开始关注unity,业余时间尝试做了个小游戏: <方块鸭快跑> (Cube Duck Run) 像素风,3d视角,色彩明快,有无尽和关卡两种模式. 应用连接: goo ...
- 【python游戏编程之旅】第九篇---嗷大喵快跑小游戏开发实例
本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 前几期博客我们一起学习了,pygame中的冲突检测技术以及一些常用的数据结构. 这次我们来一起做一个简单的酷 ...
- LYK 快跑!(LYK别打我-)(话说LYK是谁)
LYK 快跑!(run) Time Limit:5000ms Memory Limit:64MB 题目描述 LYK 陷进了一个迷宫! 这个迷宫是网格图形状的. LYK 一开始在(1,1)位置, 出口在 ...
- LYK 快跑!(run)
LYK 快跑!(run)Time Limit:5000ms Memory Limit:64MB[题目描述] LYK 陷进了一个迷宫! 这个迷宫是网格图形状的. LYK 一开始在(1,1)位置, 出口在 ...
随机推荐
- 单堆石子的Nim Game
两个人轮流捡石子,只有一堆石子,石子数为n.每个人每次至少捡一个石子,至多捡m个.取走最后一个石子的人胜利,若我方先手,求能否胜利. 若n % (m + 1)为0,则必输,否则必赢.
- luogu P2434 [SDOI2005]区间
题目描述 现给定n个闭区间[ai, bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排列 ...
- RequireJS解决代码依赖问题,异步加载js,避免页面失去相应
RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代码,但其主要目的还是为了代码的模块化.它鼓励在使用脚本时以modul ...
- app中获取应用名称,版本等信息的方法
在app中,我们有时候需要显示一些信息,例如名称,版本等等...如果用写死的方式可能不太好,我们可以动态的读取.应用的信息主要是在info.plist这个文件中,实际就是一个xml文件,以源文件的方式 ...
- 在红米note4上实现自动安装软件
因为要做自动化测试,需要对已发布的包进行回归手测,这个时候需要手动安装APK,但是红米会弹出继续安装的按钮,手点一次比较烦,想自动点"继续安装"按钮! 感谢先行者们的分享 本文参考 ...
- 【GLSL教程】(一)图形流水线 【转】
http://blog.csdn.net/racehorse/article/details/6593719 这是一些列来自lighthouse3d的GLSL教程,非常适合入门.我将边学习边翻译该教程 ...
- linux挂载硬盘
最近有个生产机由于缓存问题,硬盘不太够用,所以就加载了一块硬盘,下面把挂载硬盘的过程记录下,供大家参考,有问题欢迎留言! fdisk –l ------------------------------ ...
- mysql报错1872: Slave failed to initialize relay log info structure from the repository
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository 在一台主机上增加 ...
- SAS学习经验总结分享:篇一—数据的读取
第一篇:BASE SAS分为数据步的作用及生成数据集的方式 我是学经济相关专业毕业的,从事数据分析工作近一年,之前一直在用EXCEL,自认为EXCEL掌握的还不错. 今年5月份听说了SAS,便开始学习 ...
- Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容
© 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...