【BZOJ2732】【HNOI2012】射箭 二分+半平面交
此题重点在卡精度!!!
本地已经下载数据测试并通过了,然而$B$站上还是$WA$的,可能是$CPU$对于$long\ double$ 的资瓷不一样。
此题答案显然是可以二分出来的,设当前要监测是否能射穿前$mid$个靶子。
我们发现要穿过第i个靶子,那么$a,b$必须满足$l_i≤ax_i^2+bx_i≤r_i$。
我们简单地转化下式子,我们就可以得到$\dfrac{l_i}{x_i^2}+\dfrac{b}{x_i}≤a≤\dfrac{r_i}{x_i^2}+\dfrac{b}{x_i}$。
我们想象一个以$b$为横坐标,$a$为纵坐标的平面直角坐标系中,这一对约束可以通过两个半平面的交来表示。
不难发现满足射穿前$mid$个靶子的数对$(a,b)$,必然在这$2mid$个半平面的交内。
于是问题就转化为这2$mid$个半平面是否有交(半平面交判定)
时间复杂度:$O(n\ \log\ n)$。
#include<bits/stdc++.h>
#define M 210005
#define D long double
#define eps 1e-20
#define INF 1e15
using namespace std; int dx[M]={},dl[M]={},dr[M]={},m=; struct pt{
D x,y; pt(D X=,D Y=){x=X; y=Y;}
friend pt operator +(pt a,pt b){return pt(a.x+b.x,a.y+b.y);}
friend pt operator -(pt a,pt b){return pt(a.x-b.x,a.y-b.y);}
friend D operator *(pt a,pt b){return a.x*b.y-a.y*b.x;}
void out(){printf("(%.1Lf,%.1Lf)",x,y);}
};
struct line{
pt a,b; D ang; int id;
line(){a=pt(,); b=pt(,);}
line(pt A,pt B,int ID){ id=ID; a=A; b=B;
ang=atan2(b.y-a.y,b.x-a.x);} D getk(){return (b.y-a.y)/(b.x-a.x);}
D getb(){return a.y-a.x*getk();}
friend bool operator <(line a,line b){return a.ang<b.ang;}
friend pt operator *(line a,line b){
D k1=(b.b-a.a)*(a.b-a.a);
D k2=(a.b-a.a)*(b.a-a.a);
D t=k2/(k1+k2);
return pt(b.a.x+t*(b.b.x-b.a.x),b.a.y+t*(b.b.y-b.a.y));
}
}p[M],q[M];
bool inleft(line a,line b,line c){
pt d=a*b;
return (d-c.a)*(c.b-c.a)<=eps;
}
bool solve(int n){
int l=,r=;
for(int i=;i<=m;i++){
if(p[i].id>n) continue;
while(l<r&&(!inleft(q[r-],q[r],p[i]))) r--;
while(l<r&&(!inleft(q[l+],q[l],p[i]))) l++;
q[++r]=p[i];
}
while(l<r&&(!inleft(q[r-],q[r],q[l]))) r--;
while(l<r&&(!inleft(q[l+],q[l],q[r]))) l++;
return r-l>=;
}
int main(){
int n;scanf("%d",&n); if(n<=){printf("%d\n",n); return ;}
for(int i=;i<=n;i++) scanf("%d%d%d",dx+i,dl+i,dr+i);
int l=,r=n;
for(int i=;i<=n;i++){
D L=dl[i],R=dr[i],X=dx[i];
p[++m]=line(pt(,L/(X*X)),pt(,L/(X*X)-/X),i);
p[++m]=line(pt(,R/(X*X)-/X),pt(,R/(X*X)),i);
}
pt a1=pt(INF,INF),a2=pt(-INF,INF),a3=pt(-INF,-INF),a4=pt(INF,-INF);
p[++m]=line(a1,a2,); p[++m]=line(a2,a3,); p[++m]=line(a3,a4,); p[++m]=line(a4,a1,);
sort(p+,p+m+);
while(l<r){
int mid=(l+r+)>>;
if(solve(mid)) l=mid;
else r=mid-;
}
cout<<l<<endl;
}
【BZOJ2732】【HNOI2012】射箭 二分+半平面交的更多相关文章
- 【bzoj2732】[HNOI2012]射箭 二分+半平面交
题目描述 给出二维平面上n个与y轴平行的线段,求最大的k,使得存在一条形如$y=ax^2+bx(a<0,b>0)$的抛物线与前k条线段均有公共点 输入 输入文件第一行是一个正整数N,表示一 ...
- POJ 3525 Most Distant Point from the Sea 二分+半平面交
题目就是求多变形内部一点. 使得到任意边距离中的最小值最大. 那么我们想一下,可以发现其实求是看一个圆是否能放进这个多边形中. 那么我们就二分这个半径r,然后将多边形的每条边都往内退r距离. 求半平面 ...
- 洛谷P3222 [HNOI2012]射箭(计算几何,半平面交,双端队列)
洛谷题目传送门 设抛物线方程为\(y=ax^2+bx(a<0,b>0)\),我们想要求出一组\(a,b\)使得它尽可能满足更多的要求.这个显然可以二分答案. 如何check当前的\(mid ...
- [bzoj2732][HNOI2012]射箭
Description 沫沫最近在玩一个二维的射箭游戏,如下图所示,这个游戏中的$x$轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于$(0, ...
- POJ3525 半平面交
题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...
- 【kuangbin专题】计算几何_半平面交
1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...
- 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交
4515: [Sdoi2016]游戏 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 304 Solved: 129[Submit][Status][ ...
- poj3335 半平面交
题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...
- POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交
题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...
随机推荐
- 2018.09.17 atcoder Digit Sum(数论)
传送门 数论好题啊. 首先对于b<=sqrt(n)b<=sqrt(n)b<=sqrt(n)的情况直接枚举b判断一下就行了. 下面谈一谈如何解决b>sqrt(n)b>sqr ...
- 40 Older People Needed Less Sleep ?老年人要睡得少 ?
Older People Needed Less Sleep ?老年人要睡得少 ? ①The popular notion that older people need less sleep than ...
- UVa 10382 Watering Grass (区间覆盖贪心问题+数学)
题意:有一块长为l,宽为w的草地,在其中心线有n个喷水装置,每个装置可喷出以p为中心以r为半径的圆, 选择尽量少的装置,把草地全部润湿. 析:我个去啊,做的真恶心,看起来很简单,实际上有n多个坑啊,首 ...
- N个数的最大公约数
#include <iostream> using namespace std; int main() { int c; ]={,,,}; ;i<;i++) { ]<m[i]) ...
- 转换图片为base64
既然有了解析base64图片,那么就一定会有将图片编码格式成base64,其中解码base64用BASE64Decoder,而编码base64用BASE64Encoder, 上代码: //图片转化成b ...
- android DDMS中的内存监测工具Heap
DDMS中自带的Heap工具可以显示出当前堆内存的情况,分配内存.剩余的内存等信息. 首先是进入DDMS,运行应用,在DDMS的左边区域选中应用的包名,然后点击上方的update heap图标. 点击 ...
- java线程一
我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread).线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源,比 ...
- Java内存模型以及Volatile、Synchronize关键字的疑问
1.众所周知,java的内存模型是一个主内存,每个线程都有一个工作内存空间,那么主内存同步到工作内存是什么时候发生的呢?工作内存同步会主内存又是什么时候发生的呢? 在cpu进行线程切换时就会发生这些同 ...
- vc6.0 PK vs2010
从VC++6.0不足看VisualC++2010新特性 说起VC,有人想到维生素C(维C),有人想到风险投资(venture capital), 程序员们尤其是做底层开发的程序员或老程序员们第一感觉肯 ...
- NotMapped属性特性
NotMapped特性可以应用到领域类的属性中,Code-First默认的约定,是为所有带有get,和set属性选择器的属性创建数据列.. NotManpped特性打破了这个约定,你可以使用NotMa ...