zoukankan      html  css  js  c++  java
  • wf 2017 A 计算几何

    题意:在简单多边形内找个最长线段

    思路:最长线段至少经过两个顶点,枚举两个顶点形成的直线与多边形的交点,找到包含这两个端点的在多边形内最长连续段即可。

    判断子段是否在多边形内只需判断中点是否在多边形内即可。复杂度O(n4),但跑不满,因而水过了。

    代码:

      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define pli pair<ll, int>
     29 #define pil pair<int, ll>
     30 #define clr(a, x) memset(a, x, sizeof(a))
     31 
     32 const double pi = acos(-1.0);
     33 const int INF = 0x3f3f3f3f;
     34 const int MOD = 1e9 + 7;
     35 const double EPS = 1e-13;
     36 
     37 /*
     38 #include <ext/pb_ds/assoc_container.hpp>
     39 #include <ext/pb_ds/tree_policy.hpp>
     40 using namespace __gnu_pbds;
     41 #define TREE tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update>
     42 TREE T;
     43 */
     44 
     45 int n;
     46 inline int sgn(double x) {
     47     return x < -EPS ? -1 : (x < EPS ? 0 : 1);
     48 }
     49 struct Point {
     50     double x, y;
     51     Point () {}
     52     Point (double x, double y) : x(x), y(y) {}
     53     Point operator + (const Point &p) const {
     54         return Point(x + p.x, y + p.y);
     55     }
     56     Point operator - (const Point &p) const {
     57         return Point(x - p.x, y - p.y);
     58     }
     59     Point operator * (const double &k) const {
     60         return Point(x * k, y * k);
     61     }
     62     Point operator / (const double &k) const {
     63         return Point(x / k, y / k);
     64     }
     65     double operator | (const Point &p) const {
     66         return x * p.x + y * p.y;
     67     }
     68     double operator ^ (const Point &p) const {
     69         return x * p.y - y * p.x;
     70     }
     71     bool operator < (const Point &p) const {
     72         return sgn(x - p.x) == 0 ? y < p.y : x < p.x;
     73     }
     74     bool operator == (const Point &p) const {
     75         return sgn(x - p.x) == 0 && sgn(y - p.y) == 0;
     76     }
     77     double len2() {
     78         return x * x + y * y;
     79     }
     80     double len() {
     81         return sqrt(len2());
     82     }
     83     void output() {
     84         printf("%.6f %.6f
    ", x, y);
     85     }
     86 } p[205];
     87 struct Seg {
     88     Point s, e;
     89     Seg () {}
     90     Seg (Point s, Point e) : s(s), e(e) {}
     91     Point insect_point(const Seg &l) const {
     92         Point s2 = l.s, e2 = l.e;
     93         double k1 = (e2 - s) ^ (s2 - s);
     94         double k2 = (s2 - e) ^ (e2 - e);
     95         if (sgn(k1 + k2) == 0) return Point(2e19, 2e19);
     96         return (s * k2 + e * k1) / (k1 + k2);
     97     }
     98     bool has_point(Point p) {
     99         return (s.x - p.x) * (e.x - p.x) <= EPS && (s.y - p.y) * (e.y - p.y) <= EPS;
    100     }
    101 } l[205];
    102 bool in_Pol(Point s, Seg l[], int n) {
    103     for (int i = 1; i <= n; ++i) {
    104         if (sgn((l[i].s - s) ^ (l[i].e - s)) == 0 && l[i].has_point(s))
    105             return true;
    106     }
    107     Point e = s + Point(MOD, 0);
    108     Seg seg = Seg(s, e);
    109     int cnt = 0;
    110     for (int i = 1; i <= n; ++i) {
    111         Point p = seg.insect_point(l[i]);
    112         if (p.x < 1e19 && p.y < 1e19 && l[i].has_point(p) && seg.has_point(p)) {
    113             double miny = min(l[i].s.y, l[i].e.y);
    114             if (sgn(miny - p.y) == 0) continue;
    115             ++cnt;
    116         }
    117     }
    118     return cnt & 1;
    119 }
    120 double cal(Point p1, Point p2) {
    121     Seg line = Seg(p1, p2);
    122     vector<Point> vec;
    123     for (int i = 1; i <= n; ++i) {
    124         Point pp = line.insect_point(l[i]);
    125         if (pp.x < 1e19 && pp.y < 1e19 && l[i].has_point(pp)) {
    126             vec.pb(pp);
    127         }
    128     }
    129     int siz = vec.size();
    130     for (int i = 1; i <= n; ++i) {
    131         if (sgn((p[i] - p1) ^ (p[i] - p2))) continue;
    132         int f = 1;
    133         for (int j = 0; j < siz; ++j) {
    134             if (!sgn(vec[j].x - p[i].x) && !sgn(vec[j].y - p[i].y)) {
    135                 f = 0;
    136                 break;
    137             }
    138         }
    139         if (f) vec.pb(p[i]);
    140     }
    141     sort(vec.begin(), vec.end());
    142     if (p2 < p1) swap(p1, p2);
    143     int si = 0, ei = 0;
    144     for (int i = 0; i < vec.size(); ++i) {
    145         if (vec[i] == p1) si = i;
    146         if (vec[i] == p2) ei = i;
    147     }
    148     for (int i = si + 1; i <= ei; ++i) {
    149         Point pp = (vec[i] + vec[i - 1]) / 2;
    150         if (!in_Pol(pp, l, n)) return 0;
    151     }
    152     while (si) {
    153         Point pp = (vec[si] + vec[si - 1]) / 2;
    154         if (in_Pol(pp, l, n)) {
    155             --si;
    156         } else {
    157             break;
    158         }
    159     }
    160     while (ei + 1 < vec.size()) {
    161         Point pp = (vec[ei] + vec[ei + 1]) / 2;
    162         if (in_Pol(pp, l, n)) {
    163             ++ei;
    164         } else {
    165             break;
    166         }
    167     }
    168     return (vec[ei] - vec[si]).len();
    169 }    
    170 int main() {
    171     scanf("%d", &n);
    172     for (int i = 1; i <= n; ++i) {
    173         scanf("%lf%lf", &p[i].x, &p[i].y);
    174     }
    175     for (int i = 1; i <= n; ++i) {
    176         l[i] = Seg(p[i], p[i % n + 1]);
    177     }
    178     double ans = 0;
    179     for (int i = 1; i <= n; ++i) {
    180         for (int j = i + 1; j <= n; ++j) {
    181             double res = cal(p[i], p[j]);
    182             ans = max(ans, res);
    183         }
    184     }
    185     printf("%.12f
    ", ans);
    186     return 0;
    187 }
    188 /*
    189  6 0 0 1 0 2 1 3 0 4 0 2 -1
    190  6 0 0 1 0 2 1 3 0 4 0 2 2
    191  */
    View Code

     Update: 学会了n3的做法,不需要每次判断点是否在多边形内,线交多边形时可以把每个交点维护个状态,下交点为+,上交点为﹣,公共为1,非公共为2,平行或重合直接忽略掉,便可根据状态的前缀和判断每截线段是否在多边形内。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define pau system("pause")
     6 #define ll long long
     7 #define pii pair<int, int>
     8 #define pb push_back
     9 #define clr(a, x) memset(a, x, sizeof(a))
    10 
    11 const double pi = acos(-1.0);
    12 const int INF = 0x3f3f3f3f;
    13 const int MOD = 1e9 + 7;
    14 const double EPS = 1e-9;
    15 
    16 /*
    17 #include <ext/pb_ds/assoc_container.hpp>
    18 #include <ext/pb_ds/tree_policy.hpp>
    19 using namespace __gnu_pbds;
    20 #define TREE tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update>
    21 TREE T;
    22 */
    23 
    24 int sgn(double x) {return x < -EPS ? -1 : (x < EPS ? 0 : 1);}
    25 struct Point {
    26     double x, y;
    27     Point () {}
    28     Point (double x, double y) : x(x), y(y) {}
    29     Point operator + (const Point &p) const {return Point(x + p.x, y + p.y);}
    30     Point operator - (const Point &p) const {return Point(x - p.x, y - p.y);}
    31     Point operator * (const double &k) const {return Point(x * k, y * k);}
    32     Point operator / (const double &k) const {return Point(x / k, y / k);}
    33     double operator ^ (const Point &p) const {return x * p.y - y * p.x;}
    34     double operator | (const Point &p) const {return x * p.x + y * p.y;}
    35     bool operator < (const Point &p) const {return sgn(x - p.x) ? x < p.x : y < p.y;}
    36     double len2() {return x * x + y * y;}
    37     double len() {return sqrt(len2());}
    38     void input() {scanf("%lf%lf", &x, &y);}
    39     void output() {printf("%.6f %.6f
    ", x, y);}
    40 } p[205];
    41 struct Line {
    42     Point s, e;
    43     Line () {}
    44     Line (Point s, Point e) : s(s), e(e) {}
    45     Point operator & (const Line &l) const {
    46         double k1 = (l.s - s) ^ (l.e - s);
    47         double k2 = (l.e - e) ^ (l.s - e);
    48         return (s * k2 + e * k1) / (k1 + k2);
    49     }
    50 } l[205];
    51 struct gg {
    52     Point p; int f;
    53     bool operator < (const gg &g) const {
    54         return p < g.p;
    55     }
    56 };
    57 int n;
    58 double ans;
    59 void solve(Line key) {
    60     vector<gg> vec;
    61     for (int i = 1; i <= n; ++i) {
    62         if (!sgn((key.e - key.s) ^ (l[i].e - l[i].s))) continue;
    63         int f1 = sgn((l[i].s - key.s) ^ (key.e - key.s));
    64         int f2 = sgn((l[i].e - key.s) ^ (key.e - key.s));
    65         if (1 == f1 * f2) continue;
    66         gg g; g.p = key & l[i];
    67         g.f = (f1 < f2 ? -1 : 1) * (!f1 || !f2 ? 1 : 2);
    68         vec.pb(g);
    69     }
    70     if (vec.empty()) return;
    71     sort(vec.begin(), vec.end());
    72     int f = 0; Point s = vec[0].p;
    73     for (int i = 0; i < vec.size(); ++i) {
    74         gg g = vec[i];
    75         if (f) {
    76             ans = max(ans, (g.p - s).len());
    77         } else {
    78             s = g.p;
    79         }
    80         f += g.f;
    81     }
    82     if (f) puts("WA");
    83 }
    84 int main() {
    85     scanf("%d", &n);
    86     for (int i = 1; i <= n; ++i) {
    87         p[i].input();
    88     }
    89     for (int i = 1; i <= n; ++i) {
    90         l[i] = Line(p[i], p[i % n + 1]);
    91     }
    92     for (int i = 1; i <= n; ++i) {
    93         for (int j = i + 1; j <= n; ++j) {
    94             solve(Line(p[i], p[j]));
    95         }
    96     }
    97     printf("%.12f
    ", ans);
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    【重构笔记02】重新组织函数
    【重构笔记01】第一个案例/补齐插件
    仿iphone日历插件(beta)
    都别说工资低了,我们来一起写简单的dom选择器吧!
    【单页应用】一起来单页应用吧,实现简单微博功能!(总结)
    【单页应用】一起来单页应用吧,实现简单微博功能!(下)
    【单页应用】一起来单页应用吧,实现简单微博功能!(上)
    RequireJS与Backbone简单整合
    初探Backbone
    RequireJS学习笔记
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/10522335.html
Copyright © 2011-2022 走看看