bzoj 2732 射箭 【抛物线】 【线性规划】 【半平面交】

原创 2015年11月20日 23:04:08

从原点射出的抛物线方程y=ax^2+bx 注意没有c,开始绕了很久。

于是乎可以得出一些线性规划方程 y1<=(>=)x1^2a+x1b 其中ab为要求的量。

所以二分,用半平面交判定交是否为空。

1、半平面交是否为空R-L>1; 及如果有两个及以上向量,不为空

2、加4个边框注意方向,而且注意让交点在框内,而不是保证大于系数就行

3、题目很坑,要longdouble 而且加上fcmp就错了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>

#define ll long long
#define inf 1e15
//#define eps 1e-15
#define double long double
#define md
#define N 500010
using namespace std;
struct point { double x,y;};
struct line
{
	point a,b;
	double slop;
	int id;
	void init(double x1,double y1,double x2,double y2,int pos)
	{
		a=(point){x1,y1}; b=(point){x2,y2};
		slop=atan2(y2-y1,x2-x1);
		id=pos;
	}
}l[N],L[N],q[N];
int W=0;
point operator - (point a,point b) { return (point) {a.x-b.x,a.y-b.y};}
double operator * (point a,point b) { return a.x*b.y-a.y*b.x;}
double cmp(line a,line b) { return a.slop==b.slop?(a.b-a.a)*(b.a-a.a)>0:a.slop<b.slop;}
point inter(line a,line b)
{
	double k1,k2,t;
	k1=(b.b-a.a)*(a.b-a.a);
	k2=(a.b-a.a)*(b.a-a.a);
	t=k1/(k1+k2);
	point ans;
	ans.x=b.b.x+(b.a.x-b.b.x)*t;
	ans.y=b.b.y+(b.a.y-b.b.y)*t;
	return ans;
}

bool jud(line a,line b,line c)
{
	point p=inter(a,b);
	return (p-c.a)*(c.b-c.a)>0;
}
	
bool ok(int mid)
{
	int cnt=1;
	l[1]=L[1];
	for (int i=2;i<=W;i++)
	{
		if (L[i].id>mid) continue;
		if (L[i].slop!=L[i-1].slop) cnt++;
		l[cnt]=L[i];
	}
	//printf("mid %d\n",mid);
	//for (int i=1;i<=cnt;i++) printf("%d %lf %lf %lf %lf %d\n",i,l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].id);
	
	int L=1,R=2;
	q[1]=l[1]; q[2]=l[2];
	for (int i=3;i<=cnt;i++)
	{
		while (L<R&&jud(q[R-1],q[R],l[i])) R--;
		while (L<R&&jud(q[L+1],q[L],l[i])) L++;
		q[++R]=l[i];
	}
	while (L<R&&jud(q[R-1],q[R],q[L])) R--;
	while (L<R&&jud(q[L+1],q[L],q[R])) L++;
	return R-L>1;
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("data.in","r",stdin); freopen("data.out","w",stdout);
#endif
	int totn; 
	scanf("%d",&totn);
	L[++W].init(-inf,-inf,inf,-inf,0); L[++W].init(inf,-inf,inf,inf,0);
	L[++W].init(inf,inf,-inf,inf,0); L[++W].init(-inf,inf,-inf,-inf,0);
	for (int i=1;i<=totn;i++)
	{
		int an,bn,cn;
		double x,y1,y2;
		scanf("%d%d%d",&an,&bn,&cn);
		x=an; y1=bn; y2=cn;
		double a=-x,b=y2/x;
		L[++W].init(1,a+b,0,b,i);
		b=y1/x;
		L[++W].init(0,b,1,a+b,i);
	}
	sort(L+1,L+W+1,cmp);
	int l=0,r=totn;
	//printf("%d\n",ok(1));
	while (l!=r)
	{
		int mid=(l+r+1)>>1;
		if (ok(mid)) l=mid; else r=mid-1;
	}
	printf("%d\n",l);
	return 0;
}

[BZOJ 2732][HNOI 2012]射箭(半平面交)

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=2732思路对于每一关而言,它都对应了两个一元二次不等式,对于前nn关就需要满足2n2n个不等式...
  • qpswwww
  • qpswwww
  • 2015年03月09日 20:01
  • 836

BZOJ 2732([HNOI2012]射箭-半平面交)

2732: [HNOI2012]射箭 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 186  Solved: 104 [Submit][Status...
  • nike0good
  • nike0good
  • 2013年03月29日 14:15
  • 1752

bzoj 2732 射箭 半平面交 解题报告

沫沫最近在玩一个二维的射箭游戏
  • Hawo11
  • Hawo11
  • 2017年08月19日 20:32
  • 139

[半平面交 随机增量法] BZOJ 2732 [HNOI2012]射箭

设抛物线为y=ax2+byy=ax^2+by 那么一个限制y1
  • u014609452
  • u014609452
  • 2017年02月14日 10:40
  • 309

BZOJ 2732 HNOI 2012 射箭 半平面交

题目大意:给出一些与x轴垂直的线段,问一个经过原点的抛物线最多能按顺序经过多少条线段。 思路:总体上来说是数学题,我们来推一推。 设这个经过原点的抛物线为y = a * x ^ 2 + b...
  • jiangyuze831
  • jiangyuze831
  • 2014年11月26日 08:36
  • 1409

bzoj 2732: [HNOI2012]射箭 (二分+半平面交)

2732: [HNOI2012]射箭 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2537  Solved: 853 [Submit][St...
  • clover_hxy
  • clover_hxy
  • 2017年01月20日 23:22
  • 196

【BZOJ1038】【codevs1412】瞭望塔,半平面交/三分法

.
  • xym_CSDN
  • xym_CSDN
  • 2017年03月17日 11:02
  • 443

bzoj 2732 [HNOI2012]射箭

丧病半平面交
  • chai_jing
  • chai_jing
  • 2017年05月30日 16:18
  • 156

2D射箭抛物线

抛物线是一种很神奇的曲线,在数学中,抛物线是一个平面曲线,它是镜像对称的,并且当定向大致为U形(如果不同的方向,它仍然是抛物线)。它适用于几个表面上不同的数学描述中的任何一个,这些描述都可以被证明是完...
  • LS2333
  • LS2333
  • 2017年11月14日 16:10
  • 33

BZOJ 2732 [HNOI2012]射箭

半平面交
  • Orion_Rigel
  • Orion_Rigel
  • 2016年07月18日 22:23
  • 245
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj 2732 射箭 【抛物线】 【线性规划】 【半平面交】
举报原因:
原因补充:

(最多只允许输入30个字)