题意:在简单多边形内找个最长线段
思路:最长线段至少经过两个顶点,枚举两个顶点形成的直线与多边形的交点,找到包含这两个端点的在多边形内最长连续段即可。
判断子段是否在多边形内只需判断中点是否在多边形内即可。复杂度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 */
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 }