zoukankan      html  css  js  c++  java
  • poj 1271 && uva 10117 Nice Milk (半平面交)

    uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1058

      半平面交求面积最值。直接枚举C(20,8)的所有情况即可。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <vector>
      7 
      8 using namespace std;
      9 
     10 const int N = 22;
     11 struct Point {
     12     double x, y;
     13     Point() {}
     14     Point(double x, double y) : x(x), y(y) {}
     15 } pt[N], poly[N];
     16 template<class T> T sqr(T x) { return x * x;}
     17 
     18 typedef Point Vec;
     19 Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
     20 Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
     21 Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
     22 Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
     23 const double EPS = 1e-8;
     24 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
     25 
     26 inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
     27 inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
     28 inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
     29 inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
     30 inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
     31 inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);}
     32 
     33 struct DLine {
     34     Point p;
     35     Vec v;
     36     double ang;
     37     DLine() {}
     38     DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
     39     bool operator < (const DLine &L) const { return ang < L.ang;}
     40     DLine move(double x) { return DLine(p + normal(v) * x, v);}
     41 } dl[N];
     42 
     43 inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > 0;}
     44 inline Point dLineIntersect(DLine a, DLine b) { return a.p + a.v * (crossDet(b.v, a.p - b.p) / crossDet(a.v, b.v));}
     45 
     46 struct Poly {
     47     vector<Point> pt;
     48     Poly() { pt.clear();}
     49     ~Poly() {}
     50     Poly(vector<Point> &pt) : pt(pt) {}
     51     Point operator [] (int x) const { return pt[x];}
     52     int size() { return pt.size();}
     53     double area() {
     54         if (pt.size() < 3) return 0.0;
     55         double ret = 0.0;
     56         for (int i = 0, sz = pt.size(); i < sz; i++)
     57             ret += crossDet(pt[i], pt[(i + 1) % sz]);
     58         return fabs(ret / 2.0);
     59     }
     60 } ;
     61 
     62 Point p[N];
     63 DLine q[N];
     64 int halfPlane(DLine *L, int n) {
     65     sort(L, L + n);
     66     int fi, la;
     67     q[fi = la = 0] = L[0];
     68     for (int i = 1; i < n; i++) {
     69         while (fi < la && !onLeft(L[i], p[la - 1])) la--;
     70         while (fi < la && !onLeft(L[i], p[fi])) fi++;
     71         q[++la] = L[i];
     72         if (fabs(crossDet(q[la].v, q[la - 1].v)) < EPS) {
     73             la--;
     74             if (onLeft(q[la], L[i].p)) q[la] = L[i];
     75         }
     76         if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]);
     77     }
     78     while (fi < la && !onLeft(q[fi], p[la - 1])) la--;
     79     if (la < fi) return 0;
     80     p[la] = dLineIntersect(q[la], q[fi]);
     81     int ret = 0;
     82     for (int i = fi; i <= la; i++) poly[ret++] = p[i];
     83     return ret;
     84 }
     85 
     86 //Poly halfPlane(DLine *L, int n) {
     87 //    Poly ret = Poly();
     88 //    sort(L, L + n);
     89 //    int fi, la;
     90 //    Point *p = new Point[n];
     91 //    DLine *q = new DLine[n];
     92 //    q[fi = la = 0] = L[0];
     93 //    for (int i = 1; i < n; i++) {
     94 //        while (fi < la && !onLeft(L[i], p[la - 1])) la--;
     95 //        while (fi < la && !onLeft(L[i], p[fi])) fi++;
     96 //        q[++la] = L[i];
     97 //        if (fabs(crossDet(q[la].v, q[la - 1].v)) < EPS) {
     98 //            la--;
     99 //            if (onLeft(q[la], L[i].p)) q[la] = L[i];
    100 //        }
    101 //        if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]);
    102 //    }
    103 //    while (fi < la && !onLeft(q[fi], p[la - 1])) la--;
    104 //    if (la < fi) return ret;
    105 //    p[la] = dLineIntersect(q[la], q[fi]);
    106 //    for (int i = fi; i <= la; i++) ret.pt.push_back(p[i]);
    107 //    return ret;
    108 //}
    109 
    110 double polyArea(Point *p, int n) {
    111     if (n < 3) return 0.0;
    112     double sum = 0.0;
    113     p[n] = p[0];
    114     Point O = Point(0.0, 0.0);
    115     for (int i = 0; i < n; i++) sum += crossDet(O, p[i], p[i + 1]);
    116     return fabs(sum / 2.0);
    117 }
    118 
    119 double work(int st, int n, double d) {
    120 //    cout << st << endl;
    121     for (int i = 0; i < n; i++) dl[i] = DLine(pt[i], pt[i + 1] - pt[i]).move((st & (1 << i)) == 0 ? 0.0 : d);
    122     int tmp = halfPlane(dl, n);
    123     return polyArea(poly, tmp);
    124 //    Poly tmp = halfPlane(dl, n);
    125 //    return tmp.area();
    126 }
    127 
    128 int cntBit(int x) {
    129     int cnt = 0;
    130     while (x > 0) {
    131         if (x & 1) cnt++;
    132         x >>= 1;
    133     }
    134     return cnt;
    135 }
    136 
    137 int main() {
    138 //    freopen("in", "r", stdin);
    139     int n, k;
    140     double d;
    141     while (~scanf("%d%d%lf", &n, &k, &d) && (n + k + d > EPS)) {
    142         for (int i = 0; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
    143         pt[n] = pt[0];
    144         double ans = 0.0, area = polyArea(pt, n);
    145         for (int i = 0, end = 1 << n; i < end; i++) {
    146             if (cntBit(i) <= k) {
    147 //                cout << i << endl;
    148                 ans = max(ans, area - work(i, n, d));
    149             }
    150             if (sgn(ans - area) == 0) break;
    151         }
    152         printf("%.2f
    ", ans);
    153     }
    154     return 0;
    155 }
    View Code

    能通过POJ的代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <vector>
      7 
      8 using namespace std;
      9 
     10 const int N = 22;
     11 struct Point {
     12     double x, y;
     13     Point() {}
     14     Point(double x, double y) : x(x), y(y) {}
     15 } pt[N], poly[N];
     16 template<class T> T sqr(T x) { return x * x;}
     17 
     18 typedef Point Vec;
     19 Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
     20 Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
     21 Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
     22 Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
     23 const double EPS = 1e-8;
     24 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
     25 
     26 inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
     27 inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
     28 inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
     29 inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
     30 inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
     31 inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);}
     32 
     33 struct DLine {
     34     Point p;
     35     Vec v;
     36     double ang;
     37     DLine() {}
     38     DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
     39     bool operator < (const DLine &L) const { return ang < L.ang;}
     40     DLine move(double x) { return DLine(p + normal(v) * x, v);}
     41 } dl[N];
     42 
     43 inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > 0;}
     44 inline Point dLineIntersect(DLine a, DLine b) { return a.p + a.v * (crossDet(b.v, a.p - b.p) / crossDet(a.v, b.v));}
     45 
     46 struct Poly {
     47     vector<Point> pt;
     48     Poly() { pt.clear();}
     49     ~Poly() {}
     50     Poly(vector<Point> &pt) : pt(pt) {}
     51     Point operator [] (int x) const { return pt[x];}
     52     int size() { return pt.size();}
     53     double area() {
     54         if (pt.size() < 3) return 0.0;
     55         double ret = 0.0;
     56         for (int i = 0, sz = pt.size(); i < sz; i++)
     57             ret += crossDet(pt[i], pt[(i + 1) % sz]);
     58         return fabs(ret / 2.0);
     59     }
     60 } ;
     61 
     62 Point p[N];
     63 DLine q[N], tmpDL[N];
     64 int halfPlane(DLine *L, int n) {
     65     for (int i = 0; i < n; i++) tmpDL[i] = L[i];
     66     sort(L, L + n);
     67     int fi, la;
     68     q[fi = la = 0] = L[0];
     69     for (int i = 1; i < n; i++) {
     70         while (fi < la && !onLeft(L[i], p[la - 1])) la--;
     71         while (fi < la && !onLeft(L[i], p[fi])) fi++;
     72         q[++la] = L[i];
     73         if (fabs(crossDet(q[la].v, q[la - 1].v)) < EPS) {
     74             la--;
     75             if (onLeft(q[la], L[i].p)) q[la] = L[i];
     76         }
     77         if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]);
     78     }
     79     for (int i = 0; i < n; i++) L[i] = tmpDL[i];
     80     while (fi < la && !onLeft(q[fi], p[la - 1])) la--;
     81     if (la < fi) return 0;
     82     p[la] = dLineIntersect(q[la], q[fi]);
     83     int ret = 0;
     84     for (int i = fi; i <= la; i++) poly[ret++] = p[i];
     85     return ret;
     86 }
     87 
     88 double polyArea(Point *p, int n) {
     89     if (n < 3) return 0.0;
     90     double sum = 0.0;
     91     p[n] = p[0];
     92     Point O = Point(0.0, 0.0);
     93     for (int i = 0; i < n; i++) sum += crossDet(O, p[i], p[i + 1]);
     94     return fabs(sum / 2.0);
     95 }
     96 
     97 double work(int st, int n, double d) {
     98 //    cout << st << endl;
     99     for (int i = 0; i < n; i++) dl[i] = DLine(pt[i], pt[i + 1] - pt[i]).move((st & (1 << i)) == 0 ? 0.0 : d);
    100     int tmp = halfPlane(dl, n);
    101     return polyArea(poly, tmp);
    102 //    Poly tmp = halfPlane(dl, n);
    103 //    return tmp.area();
    104 }
    105 
    106 int cntBit(int x) {
    107     int cnt = 0;
    108     while (x > 0) {
    109         if (x & 1) cnt++;
    110         x >>= 1;
    111     }
    112     return cnt;
    113 }
    114 
    115 const double FINF = 1e100;
    116 double ans, d;
    117 void dfs(int id, int tt, int used, int k) {
    118     if (id >= tt) {
    119         int tmp = halfPlane(dl, tt);
    120         ans = min(ans, polyArea(poly, tmp));
    121         return ;
    122     }
    123     dl[id] = DLine(pt[id], pt[id + 1] - pt[id]);
    124     dfs(id + 1, tt, used, k);
    125     if (used >= k) return ;
    126     dl[id] = DLine(pt[id], pt[id + 1] - pt[id]).move(d);
    127     dfs(id + 1, tt, used + 1, k);
    128 }
    129 
    130 int main() {
    131 //    freopen("in", "r", stdin);
    132     int n, k;
    133     while (~scanf("%d%d%lf", &n, &k, &d) && (n + k + d > EPS)) {
    134         for (int i = 0; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
    135         pt[n] = pt[0];
    136         double area = polyArea(pt, n);
    137         ans = FINF;
    138         dfs(0, n, 0, k);
    139         printf("%.2f
    ", area - ans);
    140     }
    141     return 0;
    142 }
    View Code

    ——written by Lyon

  • 相关阅读:
    ElasticSearch实战:Linux日志对接Kibana
    想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜
    详解CSS的Flex布局
    如何一步步在生产环境上部署django和vue
    Anisotropic Specular Shader
    Failed to install *.apk on device *: timeout
    logcat
    Android Debug Bridge
    DVI与VGA有什么区别
    Solo and Mute
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1271_uva_10117_Lyon.html
Copyright © 2011-2022 走看看