• 【GDCPC H】【HDU5243】Homework


    给出平面上的N个点 
    对于平面上的一点p,要求任何一条通过p且不经过上面N个点的直线,其两侧的点数都不少于N/3 
    问符合上面要求的点形成的区域的面积是多少

    假如一个点一侧有少于n/3个点,这个点这一侧所有点都不可能

    因此对于所有右侧恰好有n/3 - 1个点的直线做半平面交就是答案

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 #define V P
      7 const double eps = 1e-6;
      8 inline int dcmp (double x) {
      9     return x < -eps ? -1 : x > eps;
     10 }
     11 struct P {
     12     double x, y;
     13     void scan() {
     14         scanf("%lf%lf", &x, &y);
     15     }
     16     P(double _x = 0, double _y = 0) : x(_x), y(_y) { }
     17     V operator + (V a) const {
     18         return V(x + a.x, y + a.y);
     19     }
     20     V operator - (V a) const {
     21         return V(x - a.x, y - a.y);
     22     }
     23     V operator * (double p) const {
     24         return V(p * x, p * y);
     25     }
     26     V operator / (double p) const {
     27         return V(x / p, y / p);
     28     }
     29     bool operator < (P a) const {
     30         return x < a.x || (dcmp(x - a.x) == 0 && y < a.y);
     31     }
     32     bool operator == (P a) const {
     33         return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
     34     }
     35 };
     36 
     37 inline double dot(V a, V b) {
     38     return a.x * b.x + a.y * b.y;
     39 }
     40 inline double len(V a) {
     41     return sqrt(dot(a, a));
     42 }
     43 inline double dis(P a, P b) {
     44     return len(b - a);
     45 }
     46 inline double ang(V a, V b) {
     47     return acos(dot(a, b) / len(a) / len(b));
     48 }
     49 inline double cross(V a, V b) {
     50     return a.x * b.y - a.y * b.x;
     51 }
     52 inline double area(P a, P b, P c) {
     53     return cross(b - a, c - a);
     54 }
     55 V rot(V a, double p) {
     56     return V(a.x * cos(p) - a.y * sin(p), a.x * sin(p) + a.y * cos(p));
     57 }
     58 V normal(V a) {
     59     double L = len(a);
     60     return V(-a.y / L, a.x / L);
     61 }
     62 P inter(P p, V v, P q, V w) {
     63     V u = p - q;
     64     double t = cross(w, u) / cross(v, w);
     65     return p + v * t;
     66 }
     67 double dis(P p, P a, P b) {
     68     V v1 = b - a, v2 = p - a;
     69     return fabs(cross(v1, v2)) / len(v1);
     70 }
     71 double dis2(P p, P a, P b) {
     72     if (a == b) return len(p - a);
     73     V v1 = b - a, v2 = p - a, v3 = p - b;
     74     if (dcmp(dot(v1, v2)) < 0) return len(v2);
     75     else if (dcmp(dot(v1, v3)) > 0) return len(v3);
     76     else return fabs(cross(v1, v2)) / len(v1);
     77 }
     78 P proj(P p, P a, P b) {
     79     V v = b - a;
     80     return a + v * (dot(v, p - a) / dot(v, v));
     81 }
     82 bool isInter(P a1, P a2, P b1, P b2) {
     83     double c1 = cross(a2 - a1, b1 - a1), c2 = cross(a2 - a1, b2 - a1),
     84            c3 = cross(b2 - b1, a1 - b1), c4 = cross(b2 - b1, a2 - b1);
     85     return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
     86 }
     87 bool onSeg(P p, P a1, P a2) {
     88     return dcmp(cross(a1 - p, a2 - p)) == 0 && dcmp(dot(a1 - p, a2 - p)) < 0;
     89 }
     90 
     91 double area(P* p, int n) {
     92     double s = 0;
     93     p[n] = p[0];
     94     for (int i = 1; i < n; i ++)
     95         s += cross(p[i] - p[0], p[i + 1] - p[0]);
     96     return s / 2;
     97 }
     98 int graham(P* p, int n, P* ch) {
     99     sort(p, p + n);
    100     int m = 0;
    101     for (int i = 0; i < n; i ++) {
    102         while (m > 1 && cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m --;
    103         ch[m ++] = p[i];
    104     }
    105     int k = m;
    106     for (int i = n - 2; i >= 0; i --) {
    107         while (m > k && cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m --;
    108         ch[m ++] = p[i];
    109     }
    110     if (n > 1) m --;
    111     return m;
    112 }
    113 struct L {
    114     P p;
    115     V v;
    116     double ang;
    117     L() {}
    118     L(P _p, V _v) : p(_p), v(_v) { ang = atan2(v.y, v.y); }
    119     bool operator < (const L& L) const {
    120         return ang < L.ang;
    121     }
    122 };
    123 inline int get(P a) {
    124     if( a.x > 0 && a.y >= 0) return 1;
    125     if( a.x <= 0 && a.y > 0) return 2;
    126     if( a.x < 0 && a.y <= 0) return 3;
    127     if( a.x >= 0 && a.y < 0) return 4;
    128     return 0;
    129 }
    130 inline bool cmp2 (L a, L b) {
    131     return get(a.v) < get(b.v) || (get(a.v) == get(b.v) && dcmp( cross(a.v, b.v) ) >0);
    132 }
    133 bool onLeft(L l, P p) {
    134     return cross(l.v, p - l.p) > 0;
    135 }
    136 P inter(L a, L b) {
    137     return inter(a.p, a.v, b.p, b.v);
    138 }
    139 int half(L* l, int n, P* po) {
    140     sort(l, l + n, cmp2);
    141     int h, t;
    142     P *p = new P[n];
    143     L *q = new L[n];
    144     q[h = t = 0] = l[0];
    145     for (int i = 1; i < n; i ++) {
    146         while (h < t && !onLeft(l[i], p[t - 1])) t --;
    147         while (h < t && !onLeft(l[i], p[h])) h ++;
    148         q[++ t] = l[i];
    149         if (dcmp(cross(q[t].v, q[t - 1].v)) == 0) {
    150             t --;
    151             if (onLeft(q[t], l[i].p)) q[t] = l[i];
    152         }
    153         if (h < t) p[t - 1] = inter(q[t - 1], q[t]);
    154     }
    155     while (h < t && !onLeft(q[h], p[t - 1])) t --;
    156     if (t - h <= 1) return 0;
    157     p[t] = inter(q[t], q[h]);
    158     int m = 0;
    159     for (int i = h; i <= t; i ++) po[m ++] = p[i];
    160     return m;
    161 }
    162 inline bool cmp (V a, V b) {
    163     return get(a) < get(b) || (get(a) == get(b) && dcmp( cross(a, b) ) >0);
    164 }
    165 const int N = 101000;
    166 int n;
    167 P a[N], b[N], res[N];
    168 L l[N];
    169 int main() {
    170     freopen("a.in", "r", stdin);
    171     int T;
    172     scanf("%d", &T);
    173     for (int cas = 1; cas <= T; cas ++) {
    174         scanf("%d", &n);
    175         for (int i = 0; i < n; i ++)
    176             a[i].scan();
    177         int bound = n / 3 - 1, l_c = 0;
    178         for (int i = 0; i < n; i ++) {
    179             int cnt = 0;
    180             for (int j = 0; j < n; j ++)
    181                 if (j != i)
    182                     b[cnt ++] = a[j] - a[i];
    183             sort(b, b + cnt, cmp);
    184             int t = 0, sum = 0;
    185             for (int j = 0; j < cnt; j ++) {
    186                 //if (j == 1) printf("fuck %d %d
    ", dcmp(cross(b[j], b[(t + 1) % cnt])), dcmp(dot(b[j], b[(t + 1) % cnt])));
    187                 while ((dcmp(cross(b[j], b[(t + 1) % cnt])) == 1) ||
    188                         (dcmp(cross(b[j], b[(t + 1) % cnt])) == 0 &&
    189                          dcmp(dot(b[j], b[(t + 1) % cnt])) == -1)) t = (t + 1) % cnt, sum ++;
    190                 if (cnt - (sum + 1) == bound) l[l_c ++] = L(a[i], b[j]);
    191                 //if (i == 0) printf("%d
    ", sum);
    192                 if (t == j) t ++;
    193                 else {
    194                     while (dcmp(cross(b[j], b[(j + 1) % cnt])) == 0) j ++, sum --;
    195                     sum --;
    196                 }
    197             }
    198         }
    199         //printf("%d
    ", l_c);
    200         //for (int i = 0; i < l_c; i ++)
    201         //    printf("%lf %lf %lf %lf
    ", l[i].p.x, l[i].p.y, l[i].v.x, l[i].v.y);
    202         int ans = half(l, l_c, res);
    203         //printf("%d
    ", ans);
    204         //for (int i = 0; i < ans; i ++)
    205         //    printf("%lf %lf
    ", res[i].x, res[i].y);
    206         printf("Case #%d: %.6lf
    ", cas, area(res, ans));
    207     }
    208     return 0;
    209 }
  • 相关阅读:
    11、angular 的依赖注入
    gulp插件列表
    gulp 列表
    gulp 教程
    html5模板
    yeoman官网
    node.js 增删改查(原始)
    配置MongoDB
    MongoDB手稿
    node.js 手稿
  • 原文地址:https://www.cnblogs.com/tellmewtf/p/4574438.html
Copyright © 2020-2023  润新知