Advertisement
Guest User

g.cpp

a guest
Jun 26th, 2015
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.21 KB | None | 0 0
  1. //#define __GLIBCXX_DEBUG
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4.  
  5. #define rep(i, n) for(int i = 0; i < (int)(n); ++i)
  6. #define pb push_back
  7. #define ALL(a) begin(a), end(a)
  8. #define all(a) begin(a), end(a)
  9. #define mp make_pair
  10. #define F first
  11. #define S second
  12. #define SZ(a) ((int)(a.size()))
  13. #define sz(a) ((int)(a.size()))
  14. typedef long long ll;
  15. typedef pair<int, int> PI;
  16.  
  17. typedef complex<double> P;
  18. typedef pair<P, P> L;
  19. typedef vector<P> poly;
  20.  
  21. const double EPS = 1e-9;
  22. #define DI(l) ((l).second-(l).first)
  23. #define EQ(a, b) (abs((a)-(b)) < EPS)
  24. #define CCW(l, a) ccw((l).first, (l).second, (a))
  25.  
  26.  
  27. namespace std {
  28.     bool operator <(const P &a, const P &b) {
  29.         return mp(real(a), imag(a)) < mp(real(b), imag(b));
  30.     }
  31. }
  32.  
  33. double cross(const P &a, const P &b) {return imag(conj(a)*b); }
  34. double dot(const P &a, const P &b) { return real(conj(a)*b); }
  35.  
  36. int ccw(P a, P b, P c) {
  37.     double d = cross(b -= a, c -= a);
  38.     return d>EPS ? 1 : d < -EPS ? -1 : dot(b, c) < -EPS ? 2 : norm(b) + EPS < norm(c) ? -2 : 0;
  39. }
  40.  
  41.  
  42. bool parallel(const L &l, const L &m) { return EQ(cross(DI(l), DI(m)), 0); }
  43. P projection(const L &l, const P &p) { return l.first + dot(p-l.first, DI(l)) / norm(DI(l)) * DI(l); }
  44. P reflection(const L &l, const P &p) { return 2.0 * projection(l, p) - p; }
  45. bool intersectSS(const L &s, const L &t) {
  46.     return CCW(s, t.first) * CCW(s, t.second) <= 0 && CCW(t, s.first)*CCW(t, s.second)<=0;
  47. }
  48. bool intersectSP(const L&s, const P&p) {
  49.     return EQ(abs(s.first-p)+abs(s.second-p)-abs(DI(s)), 0);
  50. }
  51.  
  52. bool sameline(const L &l, const L &m) {
  53.     return parallel(l, m) && EQ(cross(DI(l), m.second-l.first), 0);
  54. }
  55.  
  56.  
  57.  
  58. P crosspoint(const L &l, const L &m) {
  59.     P a = DI(l), b = DI(m);
  60.     double A = cross(a, b), B = cross(a, l.second-m.first);
  61.     assert(!EQ(abs(A), 0));
  62.     return m.first + B / A * b;
  63. }
  64.  
  65.  
  66. poly convex_cut(const poly &v, const L &l) {
  67.     poly w;
  68.     rep(i, sz(v)) {
  69.         P a = v[i], b = v[(i+1)%sz(v)];
  70.         if (CCW(l, a) != -1) w.push_back(a);
  71.         if (CCW(l, a) * CCW(l, b) == -1) w.push_back(crosspoint(L(a, b), l));
  72.     }
  73.   return w;
  74. }
  75.  
  76.  
  77.  
  78. void merge_segments(vector<L> &ls) {
  79.     rep(i, sz(ls))
  80.         if (ls[i].second < ls[i].first)
  81.             swap(ls[i].second, ls[i].first);
  82.  
  83.     while(true) {
  84.         bool updated = false;
  85.         rep(i, sz(ls)) for(int j=i+1; j<sz(ls); j++) {
  86.             if (sameline(ls[i], ls[j]) && !CCW(ls[i], ls[j].first)) {
  87.                 ls[i] = L(min(ls[i].first, ls[j].first), max(ls[i].second, ls[j].second));
  88.                 ls[j--] = ls.back();
  89.                 ls.pop_back();
  90.                 updated = true;
  91.             }
  92.         }
  93.         if (!updated) break;
  94.     }
  95. }
  96.  
  97. vector<P> unique_points(vector<P> ps) {
  98.     vector<P> res;
  99.     for(auto p : ps) {
  100.         bool ok = true;
  101.         for(auto q : res) if (EQ(p, q)) {
  102.             ok = false;
  103.             break;
  104.         }
  105.         if (ok) res.push_back(p);
  106.     }
  107.     return res;
  108. }
  109. void stable_arrange(vector<L> ls, vector<vector<int> > &G, vector<P> &ps) {
  110.     merge_segments(ls);
  111.  
  112.     rep(i, sz(ls)) {
  113.         ps.push_back(ls[i].first);
  114.         ps.push_back(ls[i].second);
  115.         rep(j, i) if (intersectSS(ls[i], ls[j]) && !parallel(ls[i], ls[j]))
  116.             ps.push_back(crosspoint(ls[i], ls[j]));
  117.     }
  118.     sort(all(ps));
  119.     ps = unique_points(ps);
  120.  
  121.     G.assign(sz(ps), vector<int>());
  122.     rep(i, sz(ls)) {
  123.         vector<pair<double,int>> as;
  124.         rep(j, sz(ps)) if (intersectSP(ls[i], ps[j]))
  125.             as.push_back(mp(norm(ls[i].first-ps[j]), j));
  126.         sort(all(as));
  127.         rep(j, sz(as)-1) {
  128.             int a = as[j].second, b = as[j+1].second;
  129.             G[a].push_back(b);
  130.             G[b].push_back(a);
  131.         }
  132.     }
  133. }
  134.  
  135.  
  136. double signed_area(const poly &v) {
  137.     double res = 0;
  138.     rep(i, sz(v)) res += cross(v[i], v[(i+1)%sz(v)]);
  139.     return res * 0.5;
  140. }
  141.  
  142. poly planar_dual(vector<P> ps, vector<vector<int> > g) {
  143.     map<P, vector<pair<double,P>>> order;
  144.     rep(i, sz(ps)) {
  145.         vector<pair<double,P>> &a = order[ps[i]];
  146.         rep(j, sz(g[i])) {
  147.             P p = ps[g[i][j]];
  148.             assert(p != ps[i]);
  149.             a.emplace_back(arg(p-ps[i]), p);
  150.         }
  151.         sort(all(a));
  152.     }
  153.     map<L, int> M;
  154.     rep(i, sz(g)) rep(j, sz(g[i])) {
  155.         L l(ps[i], ps[g[i][j]]);
  156.         if (M.count(l)) continue;
  157.         poly v(1, l.first);
  158.         while(l.second != ps[i]) {
  159.             v.push_back(l.second);
  160.             vector<pair<double, P>> &a = order[l.second];
  161.             int index = lower_bound(all(a), make_pair(arg(l.first - l.second), l.first)) - a.begin();
  162.             assert(index != sz(a));
  163.             index = (index + sz(a)-1) % sz(a);
  164.             l = L(l.second, a[index].second);
  165.         }
  166.         if (signed_area(v) <= 0) return v;
  167.     }
  168.   assert(false);
  169. }
  170.  
  171.  
  172.  
  173. int main(int argc, char *argv[])
  174. {
  175.     int n;
  176.     while(cin >> n, n) {
  177.         poly v(n);
  178.         rep(i, n) {
  179.             double x, y;
  180.             cin >> x >> y;
  181.             v[i] = P(x, y);
  182.         }
  183.  
  184.         pair<int, double> best(0, 0);
  185.  
  186.         rep(i, sz(v)) rep(j, i) {
  187.             P p = v[i], q = v[j];
  188.       //cerr << i << " " << j << endl;
  189.             L l((p+q)*0.5, (p+q)*0.5 - (q-p)*P(0, 1));
  190.  
  191.             poly w;
  192.             for(auto p : v) w.push_back(reflection(l, p));
  193.             reverse(all(w));
  194.       const auto cv = v;
  195.             v = convex_cut(v, l);
  196.             w = convex_cut(w, l);
  197.       if(0 && i == 2 && j == 0){
  198.         cerr << endl;
  199.         for(auto x : v){
  200.           cerr << x << " ";
  201.         }
  202.         cerr << endl;
  203.  
  204.         for(auto x : w){
  205.           cerr << x << " ";
  206.         }
  207.         cerr << endl;
  208.         cerr << endl;
  209.       }
  210.      
  211.       //cerr << "hoge" << endl;
  212.             vector<L> ls;
  213.       //cerr << "hoge" << endl;      
  214.       {
  215.         vector<poly> ps;
  216.         ps.pb(v);
  217.         ps.pb(w);
  218.         for(auto x : ps) {
  219.           // for(auto p : x){
  220.           //   cerr << p << " ";
  221.           // }
  222.           // cerr << endl;
  223.                      
  224.           rep(i, sz(x)) {
  225.             ls.push_back(L(x[i], x[(i+1)%sz(x)]));
  226.           }
  227.         }
  228.       }
  229.      
  230.             vector<P> ps;
  231.             vector<vector<int>> G;
  232.             stable_arrange(ls, G, ps);
  233.  
  234.             poly x = planar_dual(ps, G);
  235.             double len = 0;
  236.       int xsize = sz(x);
  237.             rep(i, sz(x)) {
  238.                 len += abs(x[i] - x[(i+1)%sz(x)]);
  239.         L l1(x[i], x[(i + 1)%sz(x)]);
  240.         L l2(x[(i+1)%sz(x)], x[(i + 2)%sz(x)]);
  241.         if(parallel(l1, l2)){
  242.           --xsize;
  243.         }
  244.             }
  245.      
  246.       //printf("%d %.18f\n", xsize, len);
  247.             best = max(best, mp(xsize, len));
  248.  
  249.       //printf("%d, %.8f\n", best.first, best.second);
  250.      
  251.       // for(auto p : x){
  252.       //   cerr << p << " " ;
  253.       // }
  254.       // cerr << endl;
  255.       v = cv;      
  256.         }
  257.     printf("%.18f\n", best.second);    
  258.     //exit(0);
  259.     }
  260.   return 0;
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement