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\n", 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\n", 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

猜你喜欢

转载自www.cnblogs.com/BIGTOM/p/10522335.html