
半平面交基本概念
- 半平面:由不等式ax+by+c>=0确定。
- 在一个有界区域里半平面或半平面的交是一个凸多边形区域。
- n个半平面的交是一个至多n条边的凸多边形。
BZOJ 1007 水平可见直线
题意
平面直角坐标系上,有n条直线,从y为正无穷处往下看。问能看看到哪些直线?数据范围
$$n\leq50000$$题解
当一条直线不是最后半平面交的组成部分,仅当它被与它斜率相同的直线挡住,或被两条斜率不同的直线挡住。如图:

斜率:l1< l2< l3;交点横坐标:x1< x2。l2不是半平面交的组成部分,仅当x1<=x2。
即直线与比它斜率小的直线的交点,比与比它大的直线的交点横坐标大或等于。代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| using namespace std; struct line { int a,b,num; bool operator < (const line c) const { if (a==c.a) return b<c.b; return a<c.a; } }l[50010]; int q[50010]; bool v[50010]; double calc(int x,int y) { return double(l[y].b-l[x].b)/double(l[x].a-l[y].a); } int main() { int n,num=0; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&l[i].a,&l[i].b),l[i].num=i; sort(l+1,l+n+1); for (int i=1;i<=n;i++) { if(i<n&&l[i].a==l[i+1].a) continue; while(num>1&&calc(q[num],i)<=calc(q[num-1],i)) v[l[q[num]].num]=false,num--; q[++num]=i; v[l[i].num]=true; } for (int i=1;i<=n;i++) if (v[i]) printf("%d ",i); return 0; }
|
BZOJ 3190 赛车
题意
n辆赛车,赛车gi起始位于距离起跑线前进ki的位置。比赛开始后以vi速度行驶,只要它在某一时刻位于最领先位置就能得奖。求能得奖的赛车。
题解
如果画出x-t图像就能发现,每辆赛车相当于一条直线,斜率为vi。求半平面交。(代码略)
BZOJ 1038 瞭望塔
题意
H村轮廓为(x1,y1),(x2,y2)…(xn,yn)连成的折线。满足x1< x2<…xn要求在某点建一个瞭望塔,满足在瞭望塔上能看到H村的任意位置。求瞭望塔的最小高度。
题解
将折线延长求半平面交中的最低点。那么瞭望塔所建的位置一定是最低点或H村轮廓的最高点。(正好是上凸壳的最低点或下凸壳的最高点)(代码略)