· 博主受虐中...
· Delayyy君 · 真 · 神犇
· 代码仍然不堪入目
曾经写过一次半平面交...
因为完全没搞懂就稀里糊涂过了...
今早考试整个人就被虐成了渣...
推荐:
1、http://wenku.baidu.com/view/e59decfefab069dc502201f2.html
(太懒了完全没认真找)
话说御酱的作业系列还是一如既往的带感...
回正题...
其实个人认为[1]很详细了...
无非就是维护一个双端队列什么的...
不过通常来说,思想容易...代码却总是萎成渣一样...
以下代码... (原题 HNOI2012 射箭)
半平面用两点式向量存的,向量左边为半平面. (果然还是两点式容易理解... )
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define db double
using namespace std;
int tail, head, ap, v[200010], q[200010];
int x, y, z, n;
struct point { db x, y; } ser[200010];
struct plane { int r, t; point a, b; } p[200010];
db cx(point a, point b, point c) { return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y); }
point cp(plane a, plane b)
{
db sep = cx(a.a, b.a, b.b);
sep = sep / (sep - cx(a.b, b.a, b.b));
return (point) { a.a.x + (a.b.x - a.a.x) * sep, a.a.y + (a.b.y - a.a.y) * sep };
}
void setPlane(int tp, int x, int y, int t)
{
p[tp].r = x;
p[tp].t = t;
p[tp].a = (point) { 0, x ? (db) y / x : y};
p[tp].b = (point) { 1, p[tp].a.y - x};
if (tp > n) swap(p[tp].a, p[tp].b);
}
bool check(int max_t)
{
int max_n = 2 * n + 1;
ap = 0;
for (int i = 0; i <= max_n; ++i)
if (p[i].t <= max_t)
v[++ap] = i;
tail = (head = 1) - 1;
for (int i = 1; i <= ap; ++i) {
int lap = v[i];
while (head < tail && cx(p[lap].a, p[lap].b, ser[tail]) < 0) tail--;
while (head < tail && cx(p[lap].a, p[lap].b, ser[head + 1]) < 0) head++;
q[++tail] = lap;
if (tail != head)
ser[tail] = cp(p[q[tail - 1]], p[q[tail]]);
}
while (head < tail - 1 && cx(p[q[tail]].a, p[q[tail]].b, ser[head + 1]) < 0) head++;
while (head < tail - 1 && cx(p[q[head]].a, p[q[head]].b, ser[tail]) < 0) tail--;
return tail - head >= 2;
}
bool cmp(const plane &a, const plane &b) { return a.r > b.r || (a.r == b.r && a.a.y > b.a.y); }
bool cmP(const plane &a, const plane &b) { return a.r > b.r || (a.r == b.r && a.a.y < b.a.y); }
int main()
{
freopen("archery.in", "r", stdin);
freopen("archery.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d %d %d", &x, &y, &z);
setPlane(i, x, y, i);
setPlane(i + n, x, z, i);
}
setPlane(0, 0, 0, 0);
setPlane(2 * n + 1, 0, (int) 1e9, 0);
sort(p, p + n + 1, cmp);
sort(p + n + 1, p + 2 * n + 2, cmP);
int l = 1, r = n, j, ans;
for (; j = (l + r) >> 1, l <= r; )
if (check(j)) ans = j, l = j + 1;
else r = j - 1;
printf("%d", ans);
}