半平面交.....

来源:互联网 发布:大内义兴 知乎 编辑:程序博客网 时间:2024/04/30 15:11

    · 博主受虐中...

    · Delayyy君 · 真 · 神犇

    · 代码仍然不堪入目



    曾经写过一次半平面交...

    因为完全没搞懂就稀里糊涂过了...

    今早考试整个人就被虐成了渣...


    推荐:

    1、http://wenku.baidu.com/view/e59decfefab069dc502201f2.html

    (太懒了完全没认真找)


   话说御酱的作业系列还是一如既往的带感...

   回正题...

   其实个人认为[1]很详细了...

   无非就是维护一个双端队列什么的...

   不过通常来说,思想容易...代码却总是萎成渣一样...

   以下代码...  (原题 HNOI2012 射箭)

   半平面用两点式向量存的,向量左边为半平面. (果然还是两点式容易理解... )

   

#include <cstdio>#include <cstdlib>#include <algorithm>#define db doubleusing 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);}



原创粉丝点击