Submission #223864

# Submission time Handle Problem Language Result Execution time Memory
223864 2020-04-16T16:14:30 Z Bruteforceman 2circles (balkan11_2circles) C++11
70 / 100
4000 ms 6536 KB
#include <bits/stdc++.h>
using namespace std;
typedef double T;

struct pt {

  T x,y;

  pt(T x=0, T y=0): x(x), y(y) {}

  pt operator+(pt p) { return {x+p.x, y+p.y}; }

  pt operator-(pt p) { return {x-p.x, y-p.y}; }

  pt operator*(T d) { return {x*d, y*d}; }

  pt operator/(T d) { return {x/d, y/d}; } 

};

bool operator==(pt a,pt b){return a.x==b.x&&a.y==b.y;}

bool operator!=(pt a, pt b) { return !(a == b); }

ostream& operator<<(ostream& os, pt p) {

  return os << "("<< p.x << "," << p.y << ")";

}

T sq(pt p) { return p.x*p.x + p.y*p.y; }

double abs(pt p) { return sqrt(sq(p)); }

T dot(pt v, pt w) { return v.x*w.x + v.y*w.y; }

T cross(pt v, pt w) { return v.x*w.y - v.y*w.x; }

template <typename T> int sgn(T x) {

  return (T(0) < x) - (x < T(0));

}
const double eps = 1e-9;



struct line {

  pt v; T c;

  // from direction vector v and offset c

  line(pt v, T c) : v(v), c(c) {}

  // from equation ax+by=c

  line(T a, T b, T c) : v({b,-a}), c(c) {}

  // from points P and Q

  line(pt p, pt q) : v(q-p), c(cross(v,p)) {}

  T side(pt p) { return cross(v,p)-c; }

};

// intersection of two lines

bool inter(line l1, line l2, pt &out) {

  T d = cross(l1.v, l2.v);

  if(d == 0) return false;

  out = (l2.v*l1.c - l1.v*l2.c) / d; 

  return true;

}

struct hp_t {

  pt p1, p2;

  double a;

  hp_t() { }

  hp_t(pt tp1, pt tp2) : p1(tp1), p2(tp2) {

    tp2 = tp2 - tp1;

    a = atan2(tp2.y, tp2.x);

  }

  bool operator==(const hp_t &r) const {

    return fabs(a - r.a) < eps; 

  }

  bool operator<(hp_t &r) {

    if(fabs(a - r.a) < eps) 

        return cross(r.p2 - r.p1, p2 - r.p1) >= -eps;

    else return a < r.a;

  }

} hp[50010];



int cnt;

void addhp(pt p1, pt p2) { 
  // cout << p1.x << " " << p1.y << " to " << p2.x << " " << p2.y << endl;
  hp[++cnt] = hp_t(p1, p2); 
}



double maxd = 1e8;

void init() {

  cnt = 0;

  addhp(pt(-maxd, -maxd), pt(maxd, -maxd));

  addhp(pt(maxd, -maxd), pt(maxd, maxd));

  addhp(pt(maxd, maxd), pt(-maxd, maxd));

  addhp(pt(-maxd, maxd), pt(-maxd, -maxd));

}

bool checkhp(hp_t h1, hp_t h2, hp_t h3) {

  pt p; 

  inter(line(h1.p1, h1.p2), line(h2.p1, h2.p2), p);

  return cross(p - h3.p1, h3.p2 - h3.p1) > eps;

}

vector<pt> ishp() {

  sort(hp + 1, hp + 1 + cnt);

  cnt = unique(hp + 1, hp + 1 + cnt) - hp - 1;

  deque<hp_t> dq;

  dq.push_back(hp[1]);

  dq.push_back(hp[2]);

  for (int i = 3; i <= cnt; ++i) {

    while (dq.size() > 1 && checkhp(*----dq.end(), 

              *--dq.end(), hp[i])) dq.pop_back();

    while (dq.size() > 1 && checkhp(*++dq.begin(), 

              *dq.begin(), hp[i])) dq.pop_front();

    dq.push_back(hp[i]);

  }

  while (dq.size() > 1 && checkhp(*----dq.end(), 

            *--dq.end(), dq.front())) dq.pop_back();

  while (dq.size() > 1 && checkhp(*++dq.begin(), 

            *dq.begin(), dq.back())) dq.pop_front();

  dq.push_front(dq.back());

  vector<pt> res;

  while (dq.size() > 1) {

    hp_t tmp = dq.front();

    dq.pop_front();

    pt I; 

    inter(line(tmp.p1, tmp.p2), 

          line(dq.front().p1, dq.front().p2), I);

    res.push_back(I);

  }

  return res;

}

int n;
pt v[50010];
pt orthogonal(pt a, double len) {
  double x = -a.y;
  double y = a.x;
  double mag = sqrt(x*x + y*y);
  return pt(x * (len / mag), y * (len / mag));
}
double diameter(vector <pt> v) {
  double ans = 0;
  for(int i = 0; i < v.size(); i++) {
    for(int j = 0; j < v.size(); j++) {
      ans = max(ans, dot(v[i] - v[j], v[i] - v[j]));
    }
  }
  return sqrt(ans) / 2;
}

bool good(double g) {
  cnt = 0;
  init();
  for(int i = 0; i < n; i++) {
    pt shift = orthogonal(v[(i + 1) % n] - v[i], g);
    addhp(v[i] + shift, v[(i + 1) % n] + shift);
//     cout << shift.x << ' ' << shift.y << endl;
  }
  vector <pt> p = ishp();
  return diameter(p) >= g; 
}  

int main() {
  cin >> n;
  for(int i = 0; i < n; i++) {
    cin >> v[i].x >> v[i].y;
  }
  double l = 0, r = 3e7;
  for(int i = 0; i < 100; i++) {
    double m = (l + r) * 0.5;
    if(good(m)) l = m;
    else r = m;
  }
  cout << setprecision(3) << fixed << l << endl;
  return 0;
}

Compilation message

twocircles.cpp: In function 'double diameter(std::vector<pt>)':
twocircles.cpp:221:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 0; i < v.size(); i++) {
                  ~~^~~~~~~~~~
twocircles.cpp:222:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int j = 0; j < v.size(); j++) {
                    ~~^~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 6 ms 3072 KB Output is correct
2 Correct 6 ms 3072 KB Output is correct
3 Correct 9 ms 3072 KB Output is correct
4 Correct 10 ms 3072 KB Output is correct
5 Correct 66 ms 3200 KB Output is correct
6 Execution timed out 4097 ms 4016 KB Time limit exceeded
7 Correct 804 ms 3960 KB Output is correct
8 Correct 473 ms 4176 KB Output is correct
9 Execution timed out 4070 ms 5164 KB Time limit exceeded
10 Execution timed out 4086 ms 6536 KB Time limit exceeded