【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个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...
随机推荐
- delphi XE7 数组操作中缺少的find(POS)功能
delphi xe7 中对数组操作做了很多扩充,比如加入了类似字符串处理的功能. 例如,数组相加 var A: array of integer; B: TBytes = [1,2,3,4]; //I ...
- 2018.10.20 NOIP模拟 面包(数学期望)
传送门 把方差的式子拆开. 方差=平方的期望-期望的平方. 显然只用维护点对的个数和总方案数就行了. 利用分步的思想来统计. 要统计覆盖一个矩形(x1,y1,x2,y2)(x1,y1,x2,y2)(x ...
- spring cloud--------------------HystrixCommand使用
一.注解使用: (一)注解同步执行 1.注解开启断路器功能 @EnableCircuitBreaker 2.方法事例 @HystrixCommand(fallbackMethod = "er ...
- class和struct
相同点 实际上可以使用这两个关键字定义任何一个类. 区别 1.struct的默认成员访问说明符为public,class的默认成员访问说明符为private(什么叫默认?就是没有写明public.pr ...
- jQueryUI datepicker 报错: TypeError: inst is undefined
前提:要引用的js等都引用好了 调用日期控件的input: <input id="starttime" name="starttime" class=&q ...
- The First Android App----Adding the Action Bar
In its most basic form, the action bar displays the title for the activity and the app icon on the l ...
- HDU1241 Oil Deposits 2016-07-24 13:38 66人阅读 评论(0) 收藏
Oil Deposits Problem Description The GeoSurvComp geologic survey company is responsible for detectin ...
- linux下怎样用c语言调用shell命令
C程序调用shell脚本共同拥有三种法子 :system().popen().exec系列数call_exec1.c , system() 不用你自己去产生进程.它已经封装了,直接增加自己的命令 ex ...
- iterm2 学习笔记
itrem 笔记 选中即复制,有两种方式. 在新Tab中自动使用前一Tab路径,该怎么用? 系统热键:option+space 自动完成:输入打头几个字母,然后输入command+“;” iterm2 ...
- Java何时该使用覆盖?
在Java编程中,什么时候该使用覆盖函数操作呢,很多人都知道有覆盖操作,但是到底什么时候该使用覆盖操作,还是有一些模糊的感觉,以下就举例来用代码分析就明白了, 举例生活中的案例,模拟制造手机的公司: ...