sgu 277 動態凸包

來源:互聯網
上載者:User

做法和上一篇的那個題一樣,每次刪掉一個點把相應的面積加上即可,不過細節問題折騰了我一個下午,所幸AC了,不過代碼已使我目不忍視了。

刪點的時候需要考慮左右交界處要加上的是一個三角形還是兩個三角形 ,各種細節改天附圖說明,今天已經廢了

貼上代碼,有少量debug用的資料

/* 0 0 -1 0 0 -1 2 0 -2 1 0 4 1 0 0 3 3 2 5 1 2 2 1 3 0 2 3 0 1 0 0 1 1 2 0 4 1 0 0 2 1 2 2 2 2 4 6 8 0 1 1 0 2 0 3 0 0 3 0 1 -1 2 3 6 0 0 1 1 2 0 4 1 -1 -1 0 1 2 3 0 4 6 9 12 */

#include <cstdio>#include <map>#include <set>#include <vector>#include <queue>#include <cmath>#include <iostream>#include <algorithm>using namespace std;const int maxn = 100010;typedef pair<int, int> pii;typedef long long lld;#define two(i) (lld)1<<i;#define MP make_pair#define X first#define Y secondmap<int, int>::iterator it, p, q;map<int, int> convex[2];lld sum;lld cross(pii a, pii b, pii c) {  return (lld) (b.X - a.X) * (c.Y - a.Y) - (lld) (b.Y - a.Y) * (c.X - a.X);}bool judge(map<int, int> &st, int x, int y) {  if (!st.size())    return false;  if (st.find(x) != st.end())    return y >= st[x];  if (x < st.begin()->X || (--st.end())->X < x)    return false;  it = st.lower_bound(x);  p = q = it;  p--;  return cross(MP(x, y), *q, *p) <= 0;}void insert(map<int, int> &st, int x, int y) {  if (judge(st, x, y))    return;  if (st.size() < 2) {  st[x] = y;  return;   }  it = st.lower_bound(x);  q = p = it;  if (it != st.end()) {    if (it == st.begin()) {      q++;      if (it->X == x)        sum += cross(MP(x, y), *q, *it);    } else {      p--;      q++;      sum += (cross(MP(x, y), *it, *p));      if (it->X == x && q != st.end())        sum += cross(MP(x, y), *q, *it);    }  }  st[x] = y;  it = st.find(x);  lld tmp;  for (; it != st.begin();) {    p = it;    p--;    if (p == st.begin())   break;    q = p;    q--;    if ((tmp = cross(*it, *p, *q)) >= 0) {      sum += tmp;      st.erase(p);    } else  break;  }  while (true) {    p = it;    p++;    if (p == st.end())      break;    q = p;    q++;    if (q == st.end())  break;    if ((tmp = cross(*it, *p, *q)) <= 0) {      sum += -tmp;      st.erase(p);    } else   break;  }}lld Abs(lld a) {  if (a < 0)    a = -a;  return a;}void special(int x, int y) { // 上凸包與下凸包的交界處 , 如果是一條豎直的線,就需要特判了  int ax = (--convex[0].end())->X;  int bx = (--convex[1].end())->X;  if (ax == bx && x > ax) {    p = --convex[0].end();    q = --convex[1].end();    sum += Abs(cross(MP(x, y), *p, MP(q->X, -q->Y)));  }  ax = (convex[0].begin())->X;  bx = convex[1].begin()->Y;  if (ax == bx && x < ax) {    p = convex[0].begin();    q = convex[1].begin();    sum += Abs(cross(MP(x, y), *p, MP(q->X, -q->Y)));  }}int main() {  int n, x, y;  sum = 0;  int xx[3], yy[3];  for (int i = 0; i < 3; i++) {    scanf("%d%d", &x, &y);    xx[i] = x; yy[i] = y;    insert(convex[0], x, y);    insert(convex[1], x, -y);  }  sum = Abs(cross(MP(xx[0], yy[0]), MP(xx[1], yy[1]), MP(xx[2], yy[2])));  scanf("%d", &n);  while (n--) {    scanf("%d%d", &x, &y);    special(x, y);    insert(convex[0], x, y);    insert(convex[1], x, -y);    printf("%lld\n", sum);  }  return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.