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

  • 相关阅读:
    svn cleanup failed–previous operation has not finished 解决方法
    开源SNS社区系统推荐
    从网络获取图片本地保存
    MS SQL Server 数据库连接字符串
    KeepAlive
    Configure Git in debian
    sqlserver query time
    RPi Text to Speech (Speech Synthesis)
    SQL Joins with C# LINQ
    search or reseed identity columns in sqlserver 2008
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1271_uva_10117_Lyon.html
Copyright © 2011-2022 走看看