Problem:
Problem K: A Polygon And Circles
Problem
$N$個の頂点からなる凸多角形と$M$個の円の中心座標が与えられる。すべての円の半径は$r$である。
以下の条件を満たす最小の実数$r$を求めたい。
条件: 凸多角形の内部のどの点も、少なくとも一つ以上の円に内包されている。
Input
入力は以下の形式ですべて整数で与えられる。
$N$
$px_1$　$py_1$
$px_2$　$py_2$
:
$px_N$　$py_N$
$M$
$cx_1$　$cy_1$
$cx_2$　$cy_2$
:
$cx_M$　$cy_M$
$1$行目には凸多角形の頂点数を表す整数$N$が与えられる。
$2$行目から$2+N-1$行目には凸多角形の各頂点の情報が反時計周りの順で与えられる。$1+i$行目には$i$番目の頂点の座標を表す$px_i$ $py_i$が空白区切りで与えられる。
$2+N$行目には円の数を表す整数$M$が与えられる。
$2+N+1$行目から$2+N+M$行には円の中心座標の情報が与えられる。$2+N+i$行目には$i$番目の円の中心座標を表す$cx_i$ $cy_i$が空白区切りで与えられる。
Constraints
入力は以下の条件を満たす。
$3 \le N \le 100$
$1 \le M \le 100$
$-10^5 \le px_i, py_i \le 10^5$
$-10^5 \le cx_i, cy_i \le 10^5$
凸多角形の頂点のうちどの3点を選んでも、同一直線上には存在しない
Output
条件を満たす最小の円の半径 $r$ を出力する。
ただし、$10^{-5}$ までの絶対誤差または相対誤差は許容される。
Sample Input 1
4
2 3
1 2
2 1
3 2
4
1 3
1 1
3 3
3 1
Sample Output 1
1.414213562373
Sample Input 2
7
-96469 25422
-55204 -45592
-29140 -72981
98837 -86795
92303 63297
19059 96012
-67980 70342
17
-4265 -14331
33561 72343
52055 98952
-71189 60872
10459 -7512
-11981 57756
-78228 -28044
37397 -69980
-27527 -51966
22661 -16694
13759 -59976
86539 -47703
17098 31709
-62497 -70998
-57608 59799
-1904 -35574
-73860 121
Sample Output 2
75307.220122044484

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef double P_type;
typedef complex<P_type> P;
const P_type P_eps = 1e-9; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
P_type distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
P_type distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, double r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) < r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){
  
  //線分a と 直線b
  int a = ccw(b1,b2,a1);
  int b = ccw(b1,b2,a2);
  
  //線分b と 直線a
  int c = ccw(a1,a2,b1);
  int d = ccw(a1,a2,b2);
  
  return a*b < P_eps && c*d < P_eps; // T字を除く時は -P_eps
}

/* 直線線分交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){  
  int a = ccw(a1,a2,b1);
  int b = ccw(a1,a2,b2);
  
  // 直線上のとき a or b = 0 or -2 or 2
  return (a%2)*(b%2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, double r, P a1, P a2){
  return distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, double r, P a1, P a2){
  return isContainedCP(c,r,a1) &&
    isContainedCP(c,r,a2) &&
    distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円線分交点 */
pair<P,P> getCrosspointCS(P c, double r, P a1, P a2){
  //assert(isIntersectedCS(c1, r1, c2, r2));
  
  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj + e*base2, proj - e*base2};
}

/* 多角形-点包含 */
bool iscontainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

/* 射影(直線abとpからの垂線との交点) */
P getProject(P a, P b, P p){
  P base = b - a;
  return a + base * dot(p - a, base) / norm(base);
}

/* 反射(直線abを対称軸としたpの線対称の位置) */
P getReflection(P a, P b, P p){
  return p + (getProject(a, b, p) - p) * (P_type)2.0;
}


int main(){
  int n, m, x, y;
  P pxy[101], cxy[101];
  vector<P> pol;

  scanf("%d", &n);
  
  for(int i=0;i<n;i++){
    scanf("%d%d", &x, &y);
    pxy[i] = P(x, y);
    pol.push_back(pxy[i]);
  }
  pxy[n] = pxy[0];
  

  scanf("%d", &m);
  
  for(int i=0;i<m;i++){
    scanf("%d%d", &x, &y);
    cxy[i] = P(x, y);
  }

  P_type l = 0, r = 1e6;

  P_type epseps = 1e-8;
  
  while(abs(l-r) > 2e-6){
    P_type R = (l+r)/2;
    vector<P> vec; 
    
    for(int i=0;i<m;i++){
      for(int j=i+1;j<m;j++){
        if(!isIntersectedCC(cxy[i], R, cxy[j], R)) continue;
        auto gc = getCrosspointCC(cxy[i], R, cxy[j], R);

        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;

        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + e * (P_type)-1);
        //vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    P_type mone = -1;

    for(int j=0;j<n;j++){

      for(int i=0;i<m;i++){
        auto gc = getCrosspointCS(cxy[i], R, pxy[j], pxy[j+1]);
        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;
        auto em = e*mone;
        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + em);
        //vec.push_back(gc.second + e);
        vec.push_back(gc.second + em);
      }
    }

    bool res = true;
    
    for(int i=0;i<vec.size() && res;i++){
      if(iscontainedPolyP(pol, vec[i])){

        bool f = false;
        for(int j=0;j<m && !f;j++){
          f |= isContainedCP(cxy[j], R, vec[i]);
        }

        res &= f;
      }
    }

    if(res){
      r = R;
    }else{
      l = R;
    }
  }

  printf("%.10lf\n", (double)l);
  
  
  return 0;
}
accuracy: 0.35714285714285715
time_ms: 20
memory_kb: 3860
final_rank: 16

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef double P_type;
typedef complex<P_type> P;
const P_type P_eps = 1e-9; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
P_type distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
P_type distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, double r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) < r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){
  
  //線分a と 直線b
  int a = ccw(b1,b2,a1);
  int b = ccw(b1,b2,a2);
  
  //線分b と 直線a
  int c = ccw(a1,a2,b1);
  int d = ccw(a1,a2,b2);
  
  return a*b < P_eps && c*d < P_eps; // T字を除く時は -P_eps
}

/* 直線線分交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){  
  int a = ccw(a1,a2,b1);
  int b = ccw(a1,a2,b2);
  
  // 直線上のとき a or b = 0 or -2 or 2
  return (a%2)*(b%2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, double r, P a1, P a2){
  return distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, double r, P a1, P a2){
  return isContainedCP(c,r,a1) &&
    isContainedCP(c,r,a2) &&
    distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円線分交点 */
pair<P,P> getCrosspointCS(P c, double r, P a1, P a2){
  //assert(isIntersectedCS(c1, r1, c2, r2));
  
  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj + e*base2, proj - e*base2};
}

/* 多角形-点包含 */
bool iscontainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

/* 射影(直線abとpからの垂線との交点) */
P getProject(P a, P b, P p){
  P base = b - a;
  return a + base * dot(p - a, base) / norm(base);
}

/* 反射(直線abを対称軸としたpの線対称の位置) */
P getReflection(P a, P b, P p){
  return p + (getProject(a, b, p) - p) * (P_type)2.0;
}


int main(){
  int n, m, x, y;
  P pxy[101], cxy[101];
  vector<P> pol;

  scanf("%d", &n);
  
  for(int i=0;i<n;i++){
    scanf("%d%d", &x, &y);
    pxy[i] = P(x, y);
    pol.push_back(pxy[i]);
  }
  pxy[n] = pxy[0];
  

  scanf("%d", &m);
  
  for(int i=0;i<m;i++){
    scanf("%d%d", &x, &y);
    cxy[i] = P(x, y);
  }

  P_type l = 0, r = 1e6;

  P_type epseps = 1e-6;
  
  while(abs(l-r) > 5e-6){
    P_type R = (l+r)/2;
    vector<P> vec; 
    
    for(int i=0;i<m;i++){
      for(int j=i+1;j<m;j++){
        if(!isIntersectedCC(cxy[i], R, cxy[j], R)) continue;
        auto gc = getCrosspointCC(cxy[i], R, cxy[j], R);

        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;

        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + e * (P_type)-1);
        //vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    P_type mone = -1;

    for(int j=0;j<n;j++){

      for(int i=0;i<m;i++){
        auto gc = getCrosspointCS(cxy[i], R, pxy[j], pxy[j+1]);
        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;
        auto em = e*mone;
        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + em);
        //vec.push_back(gc.second + e);
        vec.push_back(gc.second + em);
      }
    }

    bool res = true;
    
    for(int i=0;i<vec.size() && res;i++){
      if(iscontainedPolyP(pol, vec[i])){

        bool f = false;
        for(int j=0;j<m && !f;j++){
          f |= isContainedCP(cxy[j], R, vec[i]);
        }

        res &= f;
      }
    }

    if(res){
      r = R;
    }else{
      l = R;
    }
  }

  printf("%.10lf\n", (double)l);
  
  
  return 0;
}
accuracy: 0.35714285714285715
time_ms: 20
memory_kb: 3728
final_rank: 15

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef double P_type;
typedef complex<P_type> P;
const P_type P_eps = 5e-9; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
P_type distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
P_type distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, double r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) < r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){
  
  //線分a と 直線b
  int a = ccw(b1,b2,a1);
  int b = ccw(b1,b2,a2);
  
  //線分b と 直線a
  int c = ccw(a1,a2,b1);
  int d = ccw(a1,a2,b2);
  
  return a*b < P_eps && c*d < P_eps; // T字を除く時は -P_eps
}

/* 直線線分交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){  
  int a = ccw(a1,a2,b1);
  int b = ccw(a1,a2,b2);
  
  // 直線上のとき a or b = 0 or -2 or 2
  return (a%2)*(b%2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, double r, P a1, P a2){
  return distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, double r, P a1, P a2){
  return isContainedCP(c,r,a1) &&
    isContainedCP(c,r,a2) &&
    distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円線分交点 */
pair<P,P> getCrosspointCS(P c, double r, P a1, P a2){
  //assert(isIntersectedCS(c1, r1, c2, r2));
  
  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj + e*base2, proj - e*base2};
}

/* 多角形-点包含 */
bool iscontainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

/* 射影(直線abとpからの垂線との交点) */
P getProject(P a, P b, P p){
  P base = b - a;
  return a + base * dot(p - a, base) / norm(base);
}

/* 反射(直線abを対称軸としたpの線対称の位置) */
P getReflection(P a, P b, P p){
  return p + (getProject(a, b, p) - p) * (P_type)2.0;
}


int main(){
  int n, m, x, y;
  P pxy[101], cxy[101];
  vector<P> pol;

  scanf("%d", &n);
  
  for(int i=0;i<n;i++){
    scanf("%d%d", &x, &y);
    pxy[i] = P(x, y);
    pol.push_back(pxy[i]);
  }
  pxy[n] = pxy[0];
  

  scanf("%d", &m);
  
  for(int i=0;i<m;i++){
    scanf("%d%d", &x, &y);
    cxy[i] = P(x, y);
  }

  P_type l = 0, r = 1e6;

  P_type epseps = 5e-7;
  
  while(abs(l-r) > 5e-6){
    P_type R = (l+r)/2;
    vector<P> vec; 
    
    for(int i=0;i<m;i++){
      for(int j=i+1;j<m;j++){
        if(!isIntersectedCC(cxy[i], R, cxy[j], R)) continue;
        auto gc = getCrosspointCC(cxy[i], R, cxy[j], R);

        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;

        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + e * (P_type)-1);
        //vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    P_type mone = -1;

    for(int j=0;j<n;j++){

      for(int i=0;i<m;i++){
        auto gc = getCrosspointCS(cxy[i], R, pxy[j], pxy[j+1]);
        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;
        auto em = e*mone;
        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + em);
        //vec.push_back(gc.second + e);
        vec.push_back(gc.second + em);
      }
    }

    bool res = true;
    
    for(int i=0;i<vec.size() && res;i++){
      if(iscontainedPolyP(pol, vec[i])){

        bool f = false;
        for(int j=0;j<m && !f;j++){
          f |= isContainedCP(cxy[j], R, vec[i]);
        }

        res &= f;
      }
    }

    if(res){
      r = R;
    }else{
      l = R;
    }
  }

  printf("%.10lf\n", (double)l);
  
  
  return 0;
}
accuracy: 0.2857142857142857
time_ms: 20
memory_kb: 3752
final_rank: 17

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef long double P_type;
typedef complex<P_type> P;
const P_type P_eps = 1e-9; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
P_type distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
P_type distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, double r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) < r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){
  
  //線分a と 直線b
  int a = ccw(b1,b2,a1);
  int b = ccw(b1,b2,a2);
  
  //線分b と 直線a
  int c = ccw(a1,a2,b1);
  int d = ccw(a1,a2,b2);
  
  return a*b < P_eps && c*d < P_eps; // T字を除く時は -P_eps
}

/* 直線線分交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){  
  int a = ccw(a1,a2,b1);
  int b = ccw(a1,a2,b2);
  
  // 直線上のとき a or b = 0 or -2 or 2
  return (a%2)*(b%2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, double r, P a1, P a2){
  return distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, double r, P a1, P a2){
  return isContainedCP(c,r,a1) &&
    isContainedCP(c,r,a2) &&
    distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円線分交点 */
pair<P,P> getCrosspointCS(P c, double r, P a1, P a2){
  //assert(isIntersectedCS(c1, r1, c2, r2));
  
  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj + e*base2, proj - e*base2};
}

/* 多角形-点包含 */
bool iscontainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

/* 射影(直線abとpからの垂線との交点) */
P getProject(P a, P b, P p){
  P base = b - a;
  return a + base * dot(p - a, base) / norm(base);
}

/* 反射(直線abを対称軸としたpの線対称の位置) */
P getReflection(P a, P b, P p){
  return p + (getProject(a, b, p) - p) * (P_type)2.0;
}


int main(){
  int n, m, x, y;
  P pxy[101], cxy[101];
  vector<P> pol;

  scanf("%d", &n);
  
  for(int i=0;i<n;i++){
    scanf("%d%d", &x, &y);
    pxy[i] = P(x, y);
    pol.push_back(pxy[i]);
  }
  pxy[n] = pxy[0];
  

  scanf("%d", &m);
  
  for(int i=0;i<m;i++){
    scanf("%d%d", &x, &y);
    cxy[i] = P(x, y);
  }

  P_type l = 0, r = 1e6;

  P_type epseps = 1e-7;
  
  while(abs(l-r) > 1e-6){
    P_type R = (l+r)/2;
    vector<P> vec; 
    
    for(int i=0;i<m;i++){
      for(int j=i+1;j<m;j++){
        if(!isIntersectedCC(cxy[i], R, cxy[j], R)) continue;
        auto gc = getCrosspointCC(cxy[i], R, cxy[j], R);

        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;

        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + e * (P_type)-1);
        //vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    P_type mone = -1;

    for(int j=0;j<n;j++){

      for(int i=0;i<m;i++){
        auto gc = getCrosspointCS(cxy[i], R, pxy[j], pxy[j+1]);
        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * epseps;
        auto em = e*mone;
        vec.push_back(gc.first + e);
        //vec.push_back(gc.first + em);
        //vec.push_back(gc.second + e);
        vec.push_back(gc.second + em);
      }
    }

    bool res = true;
    
    for(int i=0;i<vec.size() && res;i++){
      if(iscontainedPolyP(pol, vec[i])){

        bool f = false;
        for(int j=0;j<m && !f;j++){
          f |= isContainedCP(cxy[j], R, vec[i]);
        }

        res &= f;
      }
    }

    if(res){
      r = R;
    }else{
      l = R;
    }
  }

  printf("%.10lf\n", (double)l);
  
  
  return 0;
}
accuracy: 1
time_ms: 1660
memory_kb: 4048
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);++i)
#define all(a) (a).begin(),(a).end()

typedef complex<double> Point;
typedef vector<Point> VP;
const double EPS = 1e-9; // 許容誤差^2
const double INF = 1e9;
const double PI = acos(-1.0);
#define X real()
#define Y imag()
#define LE(n,m) ((n) - (m) < EPS)
#define EQ(n,m) (abs((n)-(m)) < EPS)

// 内積　dot(a,b) = |a||b|cosθ
double dot(Point a, Point b) {
    return a.X*b.X + a.Y*b.Y;
}

// 外積　cross(a,b) = |a||b|sinθ
double cross(Point a, Point b) {
    return a.X*b.Y - a.Y*b.X;
}

// 点の進行方向
int ccw(Point a, Point b, Point c) {
    b -= a;  c -= a;
    if (cross(b,c) > +EPS) return +1;  // counter clockwise
    if (cross(b,c) < -EPS) return -1;  // clockwise
    if (dot(b,c)   < -EPS) return +2;  // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line or a==b
    return 0;                          // a--c--b on line or a==c or b==c
}

// 直線と線分
bool isecLS(Point a1, Point a2, Point b1, Point b2) {
    return cross(a2-a1, b1-a1) * 
           cross(a2-a1, b2-a1) < EPS;
}

// 2直線の交点
Point crosspointLL(Point a1, Point a2, Point b1, Point b2) {
    double d1 = cross(b2-b1, b1-a1);
    double d2 = cross(b2-b1, a2-a1);
    if (EQ(d1, 0) && EQ(d2, 0)) return a1;  // same line
    assert(!EQ(d2, 0)); // 交点がない
    return a1 + d1/d2 * (a2-a1);
}

// 2円の交点
VP crosspointCC(Point a, double ar, Point b, double br) {
    VP ps;
    Point ab = b-a;
    double d = abs(ab);
    double crL = (norm(ab) + ar*ar - br*br) / (2*d);
    if (EQ(d, 0) || ar < abs(crL)) return ps;

    Point abN = ab * Point(0, sqrt(ar*ar - crL*crL) / d);
    Point cp = a + crL/d * ab;
    ps.push_back(cp + abN);
    if (!EQ(norm(abN), 0)) ps.push_back(cp - abN);
    return ps;
}

// 多角形の内部判定
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inPolygon(const VP& ps, Point p) {
    int n = ps.size();
    bool in = false;
    rep (i, n) {
        Point a = ps[i] - p;
        Point b = ps[(i + 1) % n] - p;
        if (EQ(cross(a,b), 0) && LE(dot(a,b), 0)) return 2;
        if (a.Y > b.Y) swap(a,b);
        if ((a.Y*b.Y < 0 || (a.Y*b.Y < EPS && b.Y > EPS)) && LE(cross(a, b), 0)) in = !in;
    }
    return in;
}

bool inCircle(Point p, Point c, double r){
    return abs(p-c) <= r;
}

int n,m;
// ps: n個の頂点
// cs: m個の中心
bool check(double r, VP &ps, VP &cs){
    // 全頂点が1つ以上の円に含まれている
    rep(i,n){
        bool ok = false;
        rep(j,m){
            if(inCircle(ps[i], cs[j], r)){
                ok = true;
            }
        }
        if(!ok) return false;
    }

    // 2つの中心の垂直二等分線
    rep(i,m)rep(j,i){
        Point mid = (cs[i]+cs[j])/2.0;
        double d = abs(cs[i]-mid) + 1000.0;
        VP cps = crosspointCC(cs[i],d, cs[j],d);
        rep(k,n){
            if(isecLS(cps[0],cps[1], ps[k],ps[(k+1)%n])){
                Point p = crosspointLL(cps[0],cps[1], ps[k],ps[(k+1)%n]);
                bool ok = false;
                rep(l,m){
                    if(inCircle(p,cs[l],r)) ok = true;
                }
                if(!ok) return false;
            }
        }
    }

    // 2つの円の交点が凸内なら、他の円の中に入っていたい
    rep(i,m)rep(j,i){
        VP cps = crosspointCC(cs[i],r, cs[j],r);
        for(auto p : cps)if(inPolygon(ps, p)){
            bool ok = false;
            rep(k,m)if(k!=i && k!=j){
                if(inCircle(p, cs[k], r)){
                    ok = true;
                }
            }
            if(!ok) return false;
        }
    }

    return true;
}

int main(void){
    cin>>n;
    VP ps(n);
    rep(i,n){
        double x,y;
        cin>>x>>y;
        ps[i] = Point(x,y);
    }
    cin>>m;
    VP cs(m);
    rep(i,m){
        double x,y;
        cin>>x>>y;
        cs[i] = Point(x,y);
    }
    double l = 0, r = 1000000;
    rep(loop,50){
        double radius = (l+r)/2;
        if(check(radius, ps, cs)){
            r = radius;
        }else{
            l = radius;
        }
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 3352
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);++i)
#define all(a) (a).begin(),(a).end()

typedef complex<double> Point;
typedef vector<Point> VP;
const double EPS = 1e-9; // 許容誤差^2
const double INF = 1e9;
const double PI = acos(-1.0);
#define X real()
#define Y imag()
#define LE(n,m) ((n) - (m) < EPS)
#define GE(n,m) (EPS > (m) - (n))
#define EQ(n,m) (abs((n)-(m)) < EPS)

// 内積　dot(a,b) = |a||b|cosθ
double dot(Point a, Point b) {
    return a.X*b.X + a.Y*b.Y;
}

// 外積　cross(a,b) = |a||b|sinθ
double cross(Point a, Point b) {
    return a.X*b.Y - a.Y*b.X;
}

// 点の進行方向
int ccw(Point a, Point b, Point c) {
    b -= a;  c -= a;
    if (cross(b,c) > +EPS) return +1;  // counter clockwise
    if (cross(b,c) < -EPS) return -1;  // clockwise
    if (dot(b,c)   < -EPS) return +2;  // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line or a==b
    return 0;                          // a--c--b on line or a==c or b==c
}

// 直線と線分
bool isecLS(Point a1, Point a2, Point b1, Point b2) {
    return cross(a2-a1, b1-a1) * 
           cross(a2-a1, b2-a1) < EPS;
}

// 2直線の交点
Point crosspointLL(Point a1, Point a2, Point b1, Point b2) {
    double d1 = cross(b2-b1, b1-a1);
    double d2 = cross(b2-b1, a2-a1);
    if (EQ(d1, 0) && EQ(d2, 0)) return a1;  // same line
    assert(!EQ(d2, 0)); // 交点がない
    return a1 + d1/d2 * (a2-a1);
}

// 2円の交点
VP crosspointCC(Point a, double ar, Point b, double br) {
    VP ps;
    Point ab = b-a;
    double d = abs(ab);
    double crL = (norm(ab) + ar*ar - br*br) / (2*d);
    if (EQ(d, 0) || ar < abs(crL)) return ps;

    Point abN = ab * Point(0, sqrt(ar*ar - crL*crL) / d);
    Point cp = a + crL/d * ab;
    ps.push_back(cp + abN);
    if (!EQ(norm(abN), 0)) ps.push_back(cp - abN);
    return ps;
}

// 頂点の順序（sortやmax_elementに必要）
namespace std {
    bool operator<(const Point a, const Point b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

// 凸包
// 入力1個 -> 空
// 2個以上の全て同じ点 -> 同じもの2つ
VP convexHull(VP ps) {  // 元の点集合がソートされていいならVP&に
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    VP ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;  // 余計な点も含むなら == -1 とする
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    ch.resize(k-1);
    return ch;
}

// 多角形の内部判定
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inPolygon(const VP& ps, Point p) {
    int n = ps.size();
    bool in = false;
    rep (i, n) {
        Point a = ps[i] - p;
        Point b = ps[(i + 1) % n] - p;
        if (EQ(cross(a,b), 0) && LE(dot(a,b), 0)) return 2;
        if (a.Y > b.Y) swap(a,b);
        if ((a.Y*b.Y < 0 || (a.Y*b.Y < EPS && b.Y > EPS)) && LE(cross(a, b), 0)) in = !in;
    }
    return in;
}

bool inCircle(Point p, Point c, double r){
    return abs(p-c) <= r;
}

int n,m;
// ps: n個の頂点
// cs: m個の中心
bool check(double r, VP &ps, VP &cs){
    // 全頂点が1つ以上の円に含まれている
    rep(i,n){
        bool ok = false;
        rep(j,m){
            if(inCircle(ps[i], cs[j], r)){
                ok = true;
            }
        }
        if(!ok) return false;
    }

    // 2つの中心の垂直二等分線
    rep(i,m)rep(j,i){
        Point mid = (cs[i]+cs[j])/2.0;
        double d = abs(cs[i]-mid) + 1000.0;
        VP cps = crosspointCC(cs[i],d, cs[j],d);
        rep(k,n){
            if(isecLS(cps[0],cps[1], ps[k],ps[(k+1)%n])){
                Point p = crosspointLL(cps[0],cps[1], ps[k],ps[(k+1)%n]);
                bool ok = false;
                rep(l,m){
                    if(inCircle(p,cs[l],r)) ok = true;
                }
                if(!ok) return false;
            }
        }
    }

    // 2つの円の交点が凸内なら、他の円の中に入っていたい
    rep(i,m)rep(j,i){
        VP cps = crosspointCC(cs[i],r, cs[j],r);
        for(auto p : cps)if(inPolygon(ps, p)){
            bool ok = false;
            rep(k,m)if(k!=i && k!=j){
                if(inCircle(p, cs[k], r)){
                    ok = true;
                }
            }
            if(!ok) return false;
        }
    }

    return true;
}

int main(void){
    cin>>n;
    VP ps(n);
    rep(i,n){
        double x,y;
        cin>>x>>y;
        ps[i] = Point(x,y);
    }
    cin>>m;
    VP cs(m);
    rep(i,m){
        double x,y;
        cin>>x>>y;
        cs[i] = Point(x,y);
    }
    double l = 0, r = 1000000;
    rep(loop,100){
        double radius = (l+r)/2;
        if(check(radius, ps, cs)){
            r = radius;
        }else{
            l = radius;
        }
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 3280
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);++i)
#define all(a) (a).begin(),(a).end()

typedef complex<double> Point;
typedef vector<Point> VP;
const double EPS = 1e-9; // 許容誤差^2
const double INF = 1e9;
const double PI = acos(-1.0);
#define X real()
#define Y imag()
#define LE(n,m) ((n) - (m) < EPS)
#define GE(n,m) (EPS > (m) - (n))
#define EQ(n,m) (abs((n)-(m)) < EPS)

// 内積　dot(a,b) = |a||b|cosθ
double dot(Point a, Point b) {
    return a.X*b.X + a.Y*b.Y;
}

// 外積　cross(a,b) = |a||b|sinθ
double cross(Point a, Point b) {
    return a.X*b.Y - a.Y*b.X;
}

// 点の進行方向
int ccw(Point a, Point b, Point c) {
    b -= a;  c -= a;
    if (cross(b,c) > +EPS) return +1;  // counter clockwise
    if (cross(b,c) < -EPS) return -1;  // clockwise
    if (dot(b,c)   < -EPS) return +2;  // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line or a==b
    return 0;                          // a--c--b on line or a==c or b==c
}

// 直線と線分
bool isecLS(Point a1, Point a2, Point b1, Point b2) {
    return cross(a2-a1, b1-a1) * 
           cross(a2-a1, b2-a1) < EPS;
}

// 2直線の交点
Point crosspointLL(Point a1, Point a2, Point b1, Point b2) {
    double d1 = cross(b2-b1, b1-a1);
    double d2 = cross(b2-b1, a2-a1);
    if (EQ(d1, 0) && EQ(d2, 0)) return a1;  // same line
    assert(!EQ(d2, 0)); // 交点がない
    return a1 + d1/d2 * (a2-a1);
}

// 2円の交点
VP crosspointCC(Point a, double ar, Point b, double br) {
    VP ps;
    Point ab = b-a;
    double d = abs(ab);
    double crL = (norm(ab) + ar*ar - br*br) / (2*d);
    if (EQ(d, 0) || ar < abs(crL)) return ps;

    Point abN = ab * Point(0, sqrt(ar*ar - crL*crL) / d);
    Point cp = a + crL/d * ab;
    ps.push_back(cp + abN);
    if (!EQ(norm(abN), 0)) ps.push_back(cp - abN);
    return ps;
}

// 頂点の順序（sortやmax_elementに必要）
namespace std {
    bool operator<(const Point a, const Point b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

// 凸包
// 入力1個 -> 空
// 2個以上の全て同じ点 -> 同じもの2つ
VP convexHull(VP ps) {  // 元の点集合がソートされていいならVP&に
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    VP ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;  // 余計な点も含むなら == -1 とする
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    ch.resize(k-1);
    return ch;
}

// 多角形の内部判定
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inPolygon(const VP& ps, Point p) {
    int n = ps.size();
    bool in = false;
    rep (i, n) {
        Point a = ps[i] - p;
        Point b = ps[(i + 1) % n] - p;
        if (EQ(cross(a,b), 0) && LE(dot(a,b), 0)) return 2;
        if (a.Y > b.Y) swap(a,b);
        if ((a.Y*b.Y < 0 || (a.Y*b.Y < EPS && b.Y > EPS)) && LE(cross(a, b), 0)) in = !in;
    }
    return in;
}

bool inCircle(Point p, Point c, double r){
    return abs(p-c) <= r;
}

int n,m;
// ps: n個の頂点
// cs: m個の中心
bool check(double r, VP &ps, VP &cs){
    // 全頂点が1つ以上の円に含まれている
    rep(i,n){
        bool ok = false;
        rep(j,m){
            if(inCircle(ps[i], cs[j], r)){
                ok = true;
            }
        }
        if(!ok) return false;
    }

    // 2つの中心の垂直二等分線
    rep(i,m)rep(j,i){
        Point mid = (cs[i]+cs[j])/2.0;
        double d = abs(cs[i]-mid) + 1000.0;
        VP cps = crosspointCC(cs[i],d, cs[j],d);
        rep(k,n){
            if(isecLS(cps[0],cps[1], ps[k],ps[(k+1)%n])){
                Point p = crosspointLL(cps[0],cps[1], ps[k],ps[(k+1)%n]);
                bool ok = false;
                rep(l,m){
                    if(inCircle(p,cs[l],r)) ok = true;
                }
                if(!ok) return false;
            }
        }
    }

    // 2つの円の交点が凸内なら、他の円の中に入っていたい
    rep(i,m)rep(j,i){
        VP cps = crosspointCC(cs[i],r, cs[j],r);
        for(auto p : cps)if(inPolygon(ps, p)){
            bool ok = false;
            rep(k,m)if(k!=i && k!=j){
                if(inCircle(p, cs[k], r)){
                    ok = true;
                }
            }
            if(!ok) return false;
        }
    }

    return true;
}

int main(void){
    cin>>n;
    VP ps(n);
    rep(i,n){
        double x,y;
        cin>>x>>y;
        ps[i] = Point(x,y);
    }
    ps = convexHull(ps);
    cin>>m;
    VP cs(m);
    rep(i,m){
        double x,y;
        cin>>x>>y;
        cs[i] = Point(x,y);
    }
    double l = 0, r = 1000000;
    rep(loop,100){
        double radius = (l+r)/2;
        if(check(radius, ps, cs)){
            r = radius;
        }else{
            l = radius;
        }
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 1320
memory_kb: 3356
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define EPS (1e-6)
#define EQ(a, b) (abs((a) - (b)) < EPS)

typedef complex<double> vector2;
typedef pair<vector2, vector2> line;

double dot(vector2 a, vector2 b) { return real(conj(a) * b); }
double cross(vector2 a, vector2 b) { return imag(conj(a) * b); }

vector<vector2> cc_cross(vector2 a, vector2 b, double r) {
  double d = abs(b - a);
  double rc = d / 2;
  double rs = sqrt(r * r - rc * rc);
  vector2 diff = (b - a) / d;
  return {a + diff * vector2(rc, rs), a + diff * vector2(rc, -rs)};
}

int main() {
  int n, m;
  cin >> n;
  vector<vector2> p(n);
  for (auto &e : p) {
    double x, y;
    cin >> x >> y;
    e = {x, y};
  }
  cin >> m;
  vector<vector2> c(m);
  for (auto &e : c) {
    double x, y;
    cin >> x >> y;
    e = {x, y};
  }

  double ng = 0, ok = 1e6, r;
  while (ng + EPS < ok) {
    r = (ng + ok) / 2.0;
    bool isok = true;

    vector<int> v(n, -1);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (abs(c[j] - p[i]) < r) {
          v[i] = j;
          break;
        }
      }
      if (v[i] == -1) {
        isok = false;
      }
    }

    if (isok) {
      vector<vector<bool>> g(m, vector<bool>(m));
      for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
          if (abs(c[j] - c[i]) < 2 * r) {
            g[i][j] = true;
          }
        }
      }
      for (int k = 0; k < m; k++) {
        for (int i = 0; i < m; i++) {
          for (int j = 0; j < m; j++) {
            if (g[i][k] && g[k][j]) {
              g[i][j] = true;
            }
          }
        }
      }

      for (int i = 0; i < m; i++) {
        isok &= g[0][i];
      }
    }

    if (isok) {
      vector<vector2> u;
      for (int i = 0; i < m; i++) {
        for (int j = i + 1; j < m; j++) {
          vector<vector2> w = cc_cross(c[i], c[j], r);
          for (auto e : w) {
            bool outer = true;
            for (int k = 0; k < m; k++) {
              if (k == i || k == j) {
                continue;
              }
              outer &= abs(e - c[k]) > r;
            }
            if (outer) {
              u.push_back(e);
            }
          }
        }
      }

      for (auto e : u) {
        double t = 0;
        for (int i = 0; i < n; i++) {
          int j = (i + 1) % n;
          vector2 a = p[i] - e, b = p[j] - e;
          t += atan2(cross(a, b), dot(a, b));
        }
        if (!EQ(t, 0)) {
          isok = false;
          break;
        }
      }
    }

    if (isok) {
      ok = r;
    } else {
      ng = r;
    }
  }

  cout << fixed << setprecision(6) << r << endl;
}
accuracy: 1
time_ms: 330
memory_kb: 3668
final_rank: 3

code_snippet: #include <cmath>
#include <algorithm>
#include <cassert>
#include <limits>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
namespace lc {
static const double EPS = 1e-9;
inline double abs(double x){ return std::abs(x); }
inline bool tolerant_eq(double a, double b){ return abs(a - b) < EPS; }
}
namespace lc {
struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(y)
	{ }
	Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	Point operator*(double s) const { return Point(x * s, y * s); }
	Point operator*(const Point &p) const {
		return Point(x * p.x - y * p.y, x * p.y + y * p.x);
	}
	Point operator/(double s) const { return Point(x / s, y / s); }
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
	Point unit() const { return *this / abs(); }
};
inline Point operator*(double s, const Point &p){ return p * s; }
inline bool tolerant_eq(const Point &a, const Point &b){
	return tolerant_eq(a.x, b.x) && tolerant_eq(a.y, b.y);
}
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
}
namespace lc {
struct Line {
	Point a;
	Point b;
	explicit Line(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Point projection(const Point &p) const {
		double t = dot(p - a, b - a) / (b - a).norm();
		return a + t * (b - a);
	}
	Point direction() const {
		return (b - a).unit();
	}
};
}
namespace lc {
struct Segment {
	Point a;
	Point b;
	explicit Segment(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Line to_line() const { return Line(a, b); }
};
}
namespace lc {
struct Circle {
	Point c;
	double r;
	explicit Circle(const Point &c = Point(), double r = 0.0) :
		c(c), r(r)
	{ }
};
inline bool tolerant_eq(const Circle &a, const Circle &b){
	return tolerant_eq(a.c, b.c) && tolerant_eq(a.r, b.r);
}
}
namespace lc {
inline bool intersect(const Point &a, const Segment &b){
	return (b.a - a).abs() + (b.b - a).abs() - (b.b - b.a).abs() < EPS;
}
inline bool intersect(const Segment &a, const Point &b){
	return intersect(b, a);
}
inline bool intersect(const Circle &a, const Circle &b){
	const double d = (a.c - b.c).abs();
	return d <= a.r + b.r && a.r + d >= b.r && b.r + d >= a.r;
}
}
namespace lc {
inline std::vector<Point> crossing_points(const Line &l, const Circle &c){
	const Point &p = l.projection(c.c);
	const double t = (p - c.c).abs();
	if(t > c.r + EPS){ return std::vector<Point>(); }
	if(t > c.r - EPS){ return std::vector<Point>(1, p); }
	const Point v = l.direction();
	const double d = sqrt(c.r * c.r - t * t);
	return std::vector<Point>({ p + d * v, p - d * v });
}
inline std::vector<Point> crossing_points(const Segment &s, const Circle &c){
	const std::vector<Point> cps(crossing_points(s.to_line(), c));
	std::vector<Point> result;
	for(const auto &p : cps){
		if(intersect(s, p)){ result.push_back(p); }
	}
	return result;
}
inline std::vector<Point> crossing_points(const Circle &a, const Circle &b){
	std::vector<Point> ret;
	if(!intersect(a, b)){ return ret; }
	if(tolerant_eq(a, b)){
		ret.push_back(a.c + Point(a.r, 0.0));
		ret.push_back(a.c + Point(-a.r, 0.0));
		ret.push_back(a.c + Point(0.0, a.r));
	}else{
		const double d = (a.c - b.c).abs();
		const double rc = (d * d + a.r * a.r - b.r * b.r) / (2.0 * d);
		const double rs = sqrt(a.r * a.r - rc * rc);
		const Point diff = (b.c - a.c) / d;
		const Point x = a.c + diff * Point(rc, rs);
		const Point y = a.c + diff * Point(rc, -rs);
		ret.push_back(x);
		if(!tolerant_eq(x, y)){ ret.push_back(y); }
	}
	return ret;
}
}
namespace lc {
class Polygon {
private:
	std::vector<Point> m_points;
public:
	explicit Polygon(size_t s, const Point &p = Point())
		: m_points(s, p)
	{ }
	Point &operator[](int i){ return m_points[i]; }
	Segment side(int i) const {
		return Segment(m_points[i], m_points[(i + 1) % m_points.size()]);
	}
	int size() const { return static_cast<int>(m_points.size()); }
	int contains(const Point &p) const {
		int result = -1;
		for(int i = 0; i < size(); ++i){
			Point a = m_points[i] - p;
			Point b = m_points[(i + 1) % size()] - p;
			if(a.y > b.y){ std::swap(a, b); }
			if(a.y <= 0.0 && b.y > 0.0 && cross(a, b) < 0.0){
				result = -result;
			}
			if(cross(a, b) == 0.0 && dot(a, b) <= 0.0){ return 0; }
		}
		return result;
	}
};
}
using namespace std;
int main(){
	ios_base::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(10);
	int n, m;
	cin >> n;
	lc::Polygon poly(n);
	for(int i = 0; i < n; ++i){
		cin >> poly[i].x >> poly[i].y;
	}
	cin >> m;
	vector<lc::Point> centers(m);
	for(int i = 0; i < m; ++i){
		cin >> centers[i].x >> centers[i].y;
	}
	double lo = 0, hi = 1e8;
	for(int iter = 0; iter < 100; ++iter){
		const double r = (lo + hi) / 2;
		vector<lc::Circle> circles(m);
		for(int i = 0; i < m; ++i){
			circles[i] = lc::Circle(centers[i], r);
		}
		vector<lc::Point> testers;
		for(int i = 0; i < n; ++i){ testers.push_back(poly[i]); }
		for(int i = 0; i < m; ++i){
			for(int j = 0; j < m; ++j){
				const auto cps = lc::crossing_points(circles[i], circles[j]);
				for(const auto& p : cps){
					if(poly.contains(p) >= 0){ testers.push_back(p); }
				}
			}
			for(int j = 0; j < n; ++j){
				const auto cps = lc::crossing_points(poly.side(j), circles[i]);
				for(const auto& p : cps){ testers.push_back(p); }
			}
		}
		bool accept = true;
		for(const auto& p : testers){
			bool ok = false;
			for(const auto& c : circles){
				if((c.c - p).norm() < (r - lc::EPS) * (r - lc::EPS)){
					ok = true;
					break;
				}
			}
			if(!ok){
				accept = false;
				break;
			}
		}
		if(accept){
			hi = r;
		}else{
			lo = r;
		}
	}
	cout << lo << endl;
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3544
final_rank: 1

code_snippet: #include <cmath>
#include <algorithm>
#include <cassert>
#include <limits>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
namespace lc {
static const double EPS = 1e-9;
inline double abs(double x){ return std::abs(x); }
inline bool tolerant_eq(double a, double b){ return abs(a - b) < EPS; }
}
namespace lc {
struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(y)
	{ }
	Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	Point operator*(double s) const { return Point(x * s, y * s); }
	Point operator*(const Point &p) const {
		return Point(x * p.x - y * p.y, x * p.y + y * p.x);
	}
	Point operator/(double s) const { return Point(x / s, y / s); }
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
	Point unit() const { return *this / abs(); }
};
inline Point operator*(double s, const Point &p){ return p * s; }
inline bool tolerant_eq(const Point &a, const Point &b){
	return tolerant_eq(a.x, b.x) && tolerant_eq(a.y, b.y);
}
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
}
namespace lc {
struct Line {
	Point a;
	Point b;
	explicit Line(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Point projection(const Point &p) const {
		double t = dot(p - a, b - a) / (b - a).norm();
		return a + t * (b - a);
	}
	Point direction() const {
		return (b - a).unit();
	}
};
}
namespace lc {
struct Segment {
	Point a;
	Point b;
	explicit Segment(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Line to_line() const { return Line(a, b); }
};
}
namespace lc {
struct Circle {
	Point c;
	double r;
	explicit Circle(const Point &c = Point(), double r = 0.0) :
		c(c), r(r)
	{ }
};
inline bool tolerant_eq(const Circle &a, const Circle &b){
	return tolerant_eq(a.c, b.c) && tolerant_eq(a.r, b.r);
}
}
namespace lc {
inline bool intersect(const Point &a, const Segment &b){
	return (b.a - a).abs() + (b.b - a).abs() - (b.b - b.a).abs() < EPS;
}
inline bool intersect(const Segment &a, const Point &b){
	return intersect(b, a);
}
inline bool intersect(const Circle &a, const Circle &b){
	const double d = (a.c - b.c).abs();
	return d <= a.r + b.r && a.r + d >= b.r && b.r + d >= a.r;
}
}
namespace lc {
inline std::vector<Point> crossing_points(const Line &l, const Circle &c){
	const Point &p = l.projection(c.c);
	const double t = (p - c.c).abs();
	if(t > c.r + EPS){ return std::vector<Point>(); }
	if(t > c.r - EPS){ return std::vector<Point>(1, p); }
	const Point v = l.direction();
	const double d = sqrt(c.r * c.r - t * t);
	return std::vector<Point>({ p + d * v, p - d * v });
}
inline std::vector<Point> crossing_points(const Segment &s, const Circle &c){
	const std::vector<Point> cps(crossing_points(s.to_line(), c));
	std::vector<Point> result;
	for(const auto &p : cps){
		if(intersect(s, p)){ result.push_back(p); }
	}
	return result;
}
inline std::vector<Point> crossing_points(const Circle &a, const Circle &b){
	std::vector<Point> ret;
	if(!intersect(a, b)){ return ret; }
	if(tolerant_eq(a, b)){
		ret.push_back(a.c + Point(a.r, 0.0));
		ret.push_back(a.c + Point(-a.r, 0.0));
		ret.push_back(a.c + Point(0.0, a.r));
	}else{
		const double d = (a.c - b.c).abs();
		const double rc = (d * d + a.r * a.r - b.r * b.r) / (2.0 * d);
		const double rs = sqrt(a.r * a.r - rc * rc);
		const Point diff = (b.c - a.c) / d;
		const Point x = a.c + diff * Point(rc, rs);
		const Point y = a.c + diff * Point(rc, -rs);
		ret.push_back(x);
		if(!tolerant_eq(x, y)){ ret.push_back(y); }
	}
	return ret;
}
}
namespace lc {
class Polygon {
private:
	std::vector<Point> m_points;
public:
	explicit Polygon(size_t s, const Point &p = Point())
		: m_points(s, p)
	{ }
	Point &operator[](int i){ return m_points[i]; }
	Segment side(int i) const {
		return Segment(m_points[i], m_points[(i + 1) % m_points.size()]);
	}
	int size() const { return static_cast<int>(m_points.size()); }
	int contains(const Point &p) const {
		int result = -1;
		for(int i = 0; i < size(); ++i){
			Point a = m_points[i] - p;
			Point b = m_points[(i + 1) % size()] - p;
			if(a.y > b.y){ std::swap(a, b); }
			if(a.y <= 0.0 && b.y > 0.0 && cross(a, b) < 0.0){
				result = -result;
			}
			if(cross(a, b) == 0.0 && dot(a, b) <= 0.0){ return 0; }
		}
		return result;
	}
};
}
using namespace std;
int main(){
	ios_base::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(10);
	int n, m;
	cin >> n;
	lc::Polygon poly(n);
	for(int i = 0; i < n; ++i){
		cin >> poly[i].x >> poly[i].y;
	}
	cin >> m;
	vector<lc::Point> centers(m);
	for(int i = 0; i < m; ++i){
		cin >> centers[i].x >> centers[i].y;
	}
	double lo = 0, hi = 1e6;
	for(int iter = 0; iter < 50; ++iter){
		const double r = (lo + hi) / 2;
		vector<lc::Circle> circles(m);
		for(int i = 0; i < m; ++i){
			circles[i] = lc::Circle(centers[i], r);
		}
		vector<lc::Point> testers;
		for(int i = 0; i < n; ++i){ testers.push_back(poly[i]); }
		for(int i = 0; i < m; ++i){
			for(int j = 0; j < m; ++j){
				const auto cps = lc::crossing_points(circles[i], circles[j]);
				for(const auto& p : cps){
					if(poly.contains(p) >= 0){ testers.push_back(p); }
				}
			}
			for(int j = 0; j < n; ++j){
				const auto cps = lc::crossing_points(poly.side(j), circles[i]);
				for(const auto& p : cps){ testers.push_back(p); }
			}
		}
		bool accept = true;
		for(const auto& p : testers){
			bool ok = false;
			for(const auto& c : circles){
				if((c.c - p).norm() < r * r - lc::EPS){
					ok = true;
					break;
				}
			}
			if(!ok){
				accept = false;
				break;
			}
		}
		if(accept){
			hi = r;
		}else{
			lo = r;
		}
	}
	cout << lo << endl;
	return 0;
}
accuracy: 0.47619047619047616
time_ms: 30
memory_kb: 3404
final_rank: 13

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
//#define mt make_tuple
//typedef tuple<double,int,double> tp;
//typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
const double PI=acos(-1);
const double EPS=1e-10;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
typedef complex<double> P;
typedef vector<P> G;
typedef vector<double> vd;
typedef vector<vd> vvd;

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
  L(){;}
};
struct C{
	P c;double r;
	C(const P &c,double r):c(c),r(r){}
};
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
		//return imag(a) != imag(b) ? imag(a) < imag(b) : real(a) < real(b);  
	}
	bool operator == (const P& a, const P& b) {
		return a.real()==b.real()&&a.imag()==b.imag();
	}
}
P pin(){
	double x,y;
	char d;
	cin>>x>>y;
	P p(x,y);
	return p;
}
void PIN(P* a,int n){
	rep(i,n)a[i]=pin();
}
double dot(P a,P b){
	return real(conj(a)*b);
}
double cross(P a,P b){
	return imag(conj(a)*b);
}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;                               // a--c--b on line
}
P projection(L a,P p){
	double t=dot(p-a[0],a[0]-a[1])/norm(a[0]-a[1]);
	return a[0]+t*(a[0]-a[1]);
}
P reflection(L a,P p){
	return p+2.0*(projection(a,p)-p);
}
bool intersectLL(const L &l, const L &m) {
  return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
         abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}
bool intersectLS(const L &l, const L &s) {
  return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
         cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) {
  return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
         ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
double distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
double distanceLL(const L &l, const L &m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
/*bool intersectCS(C c,const L &l){
    return (distanceLP(l,c.c) < c.r+EPS &&
            (c.r < abs(c.c-l[0]) + EPS || c.r < abs(c.c-l[1]) + EPS));
}*/
int intersectCS(C c,L l){
	if(norm(projection(l,c.c)-c.c)-c.r*c.r>EPS)return 0;
	const double d1=abs(c.c-l[0]),d2=abs(c.c-l[1]);
	if(d1<c.r+EPS&&d2<c.r+EPS)return 0;
	if(d1<c.r-EPS&&d2>c.r+EPS||d1>c.r+EPS&&d2<c.r-EPS)return 1;
	const P h=projection(l,c.c);
	if(dot(l[0]-h,l[1]-h)<0)return 2;
	return 0;
}
P crosspointSS(L a,L b){
	double t1=abs(cross(a[1]-a[0],b[0]-a[0]));
	double t2=abs(cross(a[1]-a[0],b[1]-a[0]));
	return b[0]+(b[1]-b[0])*t1/(t1+t2);
}
L crosspointCL(C c,L l){
	P pr=projection(l,c.c);
	P e=(l[1]-l[0])/abs(l[1]-l[0]);
	double tmp=c.r*c.r-norm(pr-c.c);
	if(abs(tmp)<EPS)tmp=0;
	double t=sqrt(tmp);
	P a=pr+t*e;
	P b=pr-t*e;
	if(b<a)swap(a,b);
	return L(a,b);
}
L crosspointCS(C c,L l){
	if(intersectCS(c,l)==2)return crosspointCL(c,l);
	L ret=crosspointCL(c,l);
	if(dot(l[0]-ret[0],l[1]-ret[0])<0)ret[1]=ret[0];
	else ret[0]=ret[1];
	return ret;
}
L crosspointCC(C a,C b){
	P tmp=b.c-a.c;
	double d=abs(tmp);
	double q=acos((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d));
	double t=arg(tmp);//atan(tmp.imag()/tmp.real());
	P p1=a.c+polar(a.r,t+q);
	P p2=a.c+polar(a.r,t-q);
	if(p2<p1)swap(p1,p2);
	return L(p1,p2);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
  return m[0] + B / A * (m[1] - m[0]);
}
double area(const G &g){
    double S =0;
    for(int i =0;i <g.size();i++){
        S +=(cross(g[i],g[(i+1)%g.size()]));
    }
    return abs(S/2.0);
}
bool isconvex(const G &g){
	int n=g.size();
	rep(i,n)if(ccw(g[(i+n-1)%n],g[i%n],g[(i+1)%n])==-1)return false;
	return true;
}
int inconvex(const G& g, const P& p) {
	bool in = false;
	int n=g.size();
	rep(i,n){
		P a=g[i%n]-p;
		P b=g[(i+1)%n]-p;
		if(imag(a)>imag(b))swap(a, b);
		if(imag(a)<EPS&&0<imag(b))if(cross(a,b)<0)in=!in;
		if(abs(cross(a,b))<EPS&&dot(a,b)<EPS)return 1;//ON
	}
	return in?2:0;//IN : OUT;
}
G convex_hull(G &ps) {
    int n=ps.size(),k=0;
	sort(ps.begin(), ps.end());
	G ch(2*n);
	for(int i=0;i<n;ch[k++]=ps[i++])//lower-hull
		while(k>=2&&ccw(ch[k-2],ch[k-1],ps[i])==-1)--k;//<=0  ->  ==-1
	for(int i=n-2,t=k+1;i>=0;ch[k++]=ps[i--])//upper-hull
		while(k>=t&&ccw(ch[k-2],ch[k-1],ps[i])==-1)--k;//
	ch.resize(k-1);
	return ch;
}
double convex_diameter(const G &pt) {
  const int n = pt.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(pt[i]) > imag(pt[is])) is = i;
    if (imag(pt[i]) < imag(pt[js])) js = i;
  }
  double maxd = norm(pt[is]-pt[js]);

  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
    if (cross(diff(pt,i), diff(pt,j)) >= 0) j = (j+1) % n;
    else i = (i+1) % n;
    if (norm(pt[i]-pt[j]) > maxd) {
      maxd = norm(pt[i]-pt[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}//convex_diameter(g)
G convex_cut(const G& g, const L& l) {
  G Q;
  for (int i = 0; i < g.size(); ++i) {
    P a= curr(g, i), b= next(g, i);
    if (ccw(l[0], l[1], a) != -1) Q.push_back(a);
    if (ccw(l[0], l[1], a)*ccw(l[0], l[1], b) < 0)
      Q.push_back(crosspointLL(L(a,b), l));
  }
  return Q;
}
P turn(P p,double t){
	return p*exp(P(.0,t*PI/180.0));
}
P turn2(P p,double t){
	return p*exp(P(.0,t));
}
vector<L> tangentCC(C a,C b){
	if(a.r<b.r)swap(a,b);
	double d=abs(a.c-b.c);
	vector<L>l;
	if(d<EPS)return l;
	if(a.r+b.r<d-EPS){//hanareteiru
		double t=acos((a.r+b.r)/d);
		t=t*180/PI;
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),t),b.c+turn(b.r/d*(a.c-b.c),t)));
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),-t),b.c+turn(b.r/d*(a.c-b.c),-t)));
	}else if(a.r+b.r<d+EPS){//kuttuiteiru soto
		P p=a.c+a.r/d*(b.c-a.c);
		l.pb(L(p,p+turn(b.c-a.c,90)));
	}
	if(abs(a.r-b.r)<d-EPS){//majiwatteiru
		double t1=acos((a.r-b.r)/d);
		t1=t1*180/PI;
		double t2=180-t1;
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),t1),b.c+turn(b.r/d*(a.c-b.c),-t2)));
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),-t1),b.c+turn(b.r/d*(a.c-b.c),t2)));
	}else if(abs(a.r-b.r)<d+EPS){//kuttuiteiru uti
		P p=a.c+a.r/d*(b.c-a.c);
		l.pb(L(p,p+turn(b.c-a.c,90)));
	}
	return l;
}
void printL(const L &out){
	printf("%0.9f %0.9f %0.9f %0.9f\n",out[0].real(),out[0].imag(),out[1].real(),out[1].imag());
}
C CIN(){
	P p=pin();
	double r;
	cin>>r;
	return C(p,r);
}
bool para(L a,L b){
	return (abs(cross(a[1]-a[0],b[1]-b[0]))<EPS);
}
double min(double a,double b){return a<b?a:b;}
double max(double a,double b){return a>b?a:b;}


//XY座標
#define X real()
#define Y imag()
	
// 三角形クラス
class Triangle{

private:
	//三角形の３点の座標
	P a, b, c;
	//三角形の３辺の長さ
	double edgeA,edgeB,edgeC;
	//三角形の３角の大きさ(ラジアン)
	double angleA,angleB,angleC;
	//余弦定理から３つの角度を求める関数
	double LawOfCosines(double a,double b, double c){
		return acos( (b*b+c*c-a*a) / (2.0*b*c) );
	}
	//２つのdouble型の数値が等しいかどうか
	bool equal(double a, double b){
		return (abs( a-b ) < EPS)? true : false ;
	}

public:
	//コンストラクタ(３つの点と辺と角度を初期化)
	Triangle(P p1, P p2, P p3){
		a = p1;
		b = p2;
		c = p3;
		edgeB = abs(c-a);
		edgeA = abs(b-c);
		edgeC = abs(a-b);
		angleA = LawOfCosines(edgeA,edgeB,edgeC);
		angleB = LawOfCosines(edgeB,edgeC,edgeA);
		angleC = LawOfCosines(edgeC,edgeA,edgeB);
	}
	
	double circumscribedCircleRadius(){//外接円の半径を返す
		return ( edgeA / sin(angleA) / 2.0 );
	}
	double circumscribedCircleX(){//外心(外接円の中心)のX座標を返す
		double A = sin(2.0*angleA);
		double B = sin(2.0*angleB);
		double C = sin(2.0*angleC);
		return ( (a.X * A + b.X * B + c.X * C) / (A+B+C) );
	}
	double circumscribedCircleY(){//外心(外接円の中心)のY座標を返す
		double A = sin(2.0*angleA);
		double B = sin(2.0*angleB);
		double C = sin(2.0*angleC);
		return ( (a.Y * A + b.Y * B + c.Y * C) / (A+B+C) );
	}
};

int main(){
//		Triangle Tr(a,b,c);
//		r  = Tr.circumscribedCircleRadius();
//		xp = Tr.circumscribedCircleX();
//		yp = Tr.circumscribedCircleY();

	int n;
	cin>>n;
	G g(n);
	rep(i,n){
		double a,b;
		cin>>a>>b;
		g[i]=P(a,b);
	}
	int m;
	cin>>m;
	G in(m);
	rep(i,m){
		double a,b;
		cin>>a>>b;
		in[i]=P(a,b);
	}	
	double out=0;
	rep(i,n){
		double mi=inf;
		rep(j,m)mi=min(mi,abs(g[i]-in[j]));
		out=max(out,mi);
	}//couner
//	cout<<shosu(10)<<out<<endl;
	
	rep(i,m)loop(j,i+1,m)loop(k,j+1,m){
		Triangle Tr(in[i],in[j],in[k]);
		P p(Tr.circumscribedCircleX(),Tr.circumscribedCircleY());
		if(!inconvex(g,p))continue;
		double mi=inf;
		rep(q,m)mi=min(mi,abs(p-in[q]));
		out=max(out,mi);
	}// gaisin
//	cout<<shosu(10)<<out<<endl;

	rep(i,m)loop(j,i+1,m){
		P p=in[i]+(in[j]-in[i])/2.;
		L l(p,p+P(0,1)*(in[j]-in[i]));
		rep(k,n){
			if(!intersectLS(l,L(g[k],g[(k+1)%n])))continue;
			P cr=crosspointLL(l,L(g[k],g[(k+1)%n]));
			double mi=inf;
			rep(q,m)mi=min(mi,abs(cr-in[q]));
			out=max(out,mi);
		}
	}
	
	cout<<shosu(10)<<out<<endl;
	
}
accuracy: 1
time_ms: 160
memory_kb: 3692
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);++i)
#define rep1(i,n) for(int i=1;i<=int(n);++i)
#define all(a) (a).begin(),(a).end()
#define lb(s,x) lower_bound(all(s),x)-s.begin()
#define ub(s,x) upper_bound(all(s),x)-s.begin()
#define uniq(a) a.erase(unique(all(a)),a.end())
#define debug(x) cout<<#x<<": "<<x<<endl
template<class T,class U>
ostream& operator<<(ostream& o, const pair<T,U> &p){
    o<<"("<<p.first<<", "<<p.second<<")";
    return o;
}
#define print(v) { cerr<<#v<<": [ "; for(auto _ : v) cerr<<_<<", "; cerr<<"]"<<endl; }
typedef long long ll;


typedef complex<double> Point;
typedef pair<Point, Point> Line;
typedef vector<Point> VP;
const double EPS = 1e-9; // 許容誤差^2
const double INF = 1e9;
const double PI = acos(-1.0);
#define X real()
#define Y imag()
#define LE(n,m) ((n) - (m) < EPS)
#define GE(n,m) (EPS > (m) - (n))
#define EQ(n,m) (abs((n)-(m)) < EPS)

// 内積　dot(a,b) = |a||b|cosθ
double dot(Point a, Point b) {
    return a.X*b.X + a.Y*b.Y;
}

// 外積　cross(a,b) = |a||b|sinθ
double cross(Point a, Point b) {
    return a.X*b.Y - a.Y*b.X;
}

// 点の進行方向
int ccw(Point a, Point b, Point c) {
    b -= a;  c -= a;
    if (cross(b,c) > +EPS) return +1;  // counter clockwise
    if (cross(b,c) < -EPS) return -1;  // clockwise
    if (dot(b,c)   < -EPS) return +2;  // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line or a==b
    return 0;                          // a--c--b on line or a==c or b==c
}

/* 
    交差判定　直線・線分は縮退してはならない。
    接する場合は交差するとみなす。
    縮退している := 2つのものが区別付かない状態(?)
    isec = intersect
    L = Line
    P = Point
    S = Segment
*/

// 直線と点
bool isecLP(Point a1, Point a2, Point b) {
    return abs(ccw(a1, a2, b)) != 1;
    // return EQ(cross(a2-a1, b-a1), 0); と等価
}

// 直線と直線
bool isecLL(Point a1, Point a2, Point b1, Point b2) {
    return !isecLP(a2-a1, b2-b1, 0) || isecLP(a1, b1, b2);
}

// 直線と線分
bool isecLS(Point a1, Point a2, Point b1, Point b2) {
    return cross(a2-a1, b1-a1) * 
           cross(a2-a1, b2-a1) < EPS;
}

// 線分と線分
bool isecSS(Point a1, Point a2, Point b1, Point b2) {
    return ccw(a1, a2, b1)*ccw(a1, a2, b2) <= 0 &&
           ccw(b1, b2, a1)*ccw(b1, b2, a2) <= 0;
}

// 線分と点
bool isecSP(Point a1, Point a2, Point b) {
    return !ccw(a1, a2, b);
}


/* 距離　各直線・線分は縮退してはならない */

// 点pの直線aへの射影点を返す
Point proj(Point a1, Point a2, Point p) {
    return a1 + dot(a2-a1, p-a1)/norm(a2-a1) * (a2-a1);
}

// 点pの直線aへの反射点を返す
Point reflection(Point a1, Point a2, Point p) {
    return 2.0*proj(a1, a2, p) - p;
}

//点aと点bの距離は abs(a-b)
//#define distPP(p1,p2) abs(p1-p2)

double distLP(Point a1, Point a2, Point p) {
    return abs(proj(a1, a2, p) - p);
}

double distLL(Point a1, Point a2, Point b1, Point b2) {
    return isecLL(a1, a2, b1, b2) ? 0 : distLP(a1, a2, b1);
}

double distLS(Point a1, Point a2, Point b1, Point b2) {
    return isecLS(a1, a2, b1, b2) ? 0 : min(distLP(a1, a2, b1), distLP(a1, a2, b2));
}

double distSP(Point a1, Point a2, Point p) {
    Point r = proj(a1, a2, p);
    if (isecSP(a1, a2, r)) return abs(r-p);
    //= !ccw(a1, a2, r)
    return min(abs(a1-p), abs(a2-p));
}

double distSS(Point a1, Point a2, Point b1, Point b2) {
    if (isecSS(a1, a2, b1, b2)) return 0;
    return min({
        distSP(a1, a2, b1),
        distSP(a1, a2, b2),
        distSP(b1, b2, a1),
        distSP(b1, b2, a2)});
}

// 2直線の交点
Point crosspointLL(Point a1, Point a2, Point b1, Point b2) {
    double d1 = cross(b2-b1, b1-a1);
    double d2 = cross(b2-b1, a2-a1);
    if (EQ(d1, 0) && EQ(d2, 0)) return a1;  // same line
    assert(!EQ(d2, 0)); // 交点がない
    return a1 + d1/d2 * (a2-a1);
}


/* 円 */

double distLC(Point a1, Point a2, Point c, double r) {
    return max(distLP(a1, a2, c) - r, 0.0);
}

double distSC(Point a1, Point a2, Point c, double r) {
    double dSqr1 = norm(c-a1), dSqr2 = norm(c-a2);
    if ((dSqr1 < r*r) ^ (dSqr2 < r*r)) return 0;  // 円が線分を包含するとき距離0ならここをORに変える
    if ((dSqr1 < r*r) & (dSqr2 < r*r)) return r - sqrt(max(dSqr1, dSqr2));
    return max(distSP(a1, a2, c) - r, 0.0);
}

VP crosspointLC(Point a1, Point a2, Point c, double r) {
    VP ps;
    Point ft = proj(a1, a2, c);
    if(!GE(r*r,norm(ft-c))) return ps;
    Point dir = sqrt(max(r*r - norm(ft-c), 0.0)) / abs(a2-a1) * (a2-a1);
    ps.push_back(ft + dir);
    if (!EQ(r*r, norm(ft-c))) ps.push_back(ft - dir);
    return ps;
}

double distCC(Point a, double ar, Point b, double br) {
    double d = abs(a-b);
    return GE(d, abs(ar-br)) ? max(d-ar-br, 0.0) : abs(ar-br) - d;
}

// 2円の交点
VP crosspointCC(Point a, double ar, Point b, double br) {
    VP ps;
    Point ab = b-a;
    double d = abs(ab);
    double crL = (norm(ab) + ar*ar - br*br) / (2*d);
    if (EQ(d, 0) || ar < abs(crL)) return ps;

    Point abN = ab * Point(0, sqrt(ar*ar - crL*crL) / d);
    Point cp = a + crL/d * ab;
    ps.push_back(cp + abN);
    if (!EQ(norm(abN), 0)) ps.push_back(cp - abN);
    return ps;
}


// // 2円の交点(自作)
// VP crosspointCC(Point a, double ar, Point b, double br){
//     double d = abs(b-a);
//     if(abs(ar-br)>d || abs(ar+br)<d) return {};
//     double t = acos(double((d*d+ar*ar-br*br)/(2*d*ar)));
//     Point p1 = a+polar(ar,arg(b-a)+t);
//     Point p2 = a+polar(ar,arg(b-a)-t);
//     if(abs(p1-p2) < EPS) return {p1};
//     return {p1,p2};
// }


// 点pから円aへの接線の接点
VP tangentPoints(Point a, double ar, Point p) {
    VP ps;
    double sin = ar / abs(p-a);
    if (!LE(sin, 1)) return ps;  // ここでNaNも弾かれる
    double t = PI/2.0 - asin(min(sin, 1.0));
    ps.push_back(                 a + (p-a)*polar(sin, t));
    if (!EQ(sin, 1)) ps.push_back(a + (p-a)*polar(sin, -t));
    return ps;
}

// 2円の共通接線。返される各直線に含まれる頂点は円との接点となる
vector<Line> tangentLines(Point a, double ar, Point b, double br) {
    vector<Line> ls;
    double d = abs(b-a);
    rep (i,2) {
        double sin = (ar - (1-i*2)*br) / d;
        if (!LE(sin*sin, 1)) break;
        double cos = sqrt(max(1 - sin*sin, 0.0));
        rep (j,2) {
            Point n = (b-a) * Point(sin, (1-j*2)*cos) / d;
            ls.push_back(Line(a + ar*n, b + (1-i*2)*br*n));
            if (cos < EPS) break;  // 重複する接線を無視（重複していいならこの行不要）
        }
    }
    return ls;
}

// 三角形の外心。点a,b,cは同一線上にあってはならない
Point circumcenter(Point a, Point b, Point c) {
    a = (a-c)*0.5;
    b = (b-c)*0.5;
    return c + crosspointLL(a, a*Point(1,1), b, b*Point(1,1));
}

// 点aと点bを通り、半径がrの円の中心を返す
VP circlesPointsRadius(Point a, Point b, double r) {
    VP cs;
    Point abH = (b-a)*0.5;
    double d = abs(abH);
    if (d == 0 || d > r) return cs;  // 必要なら !LE(d,r) として円1つになる側へ丸める
    double dN = sqrt(r*r - d*d);          // 必要なら max(r*r - d*d, 0) とする
    Point n = abH * Point(0,1) * (dN / d);
    cs.push_back(a + abH + n);
    if (dN > 0) cs.push_back(a + abH - n);
    return cs;
}

// 点aと点bを通り、直線lに接する円の中心
VP circlesPointsTangent(Point a, Point b, Point l1, Point l2) {
    Point n = (l2-l1) * Point(0,1);
    Point m = (b-a) * Point(0,0.5);
    double rC = dot((a+b)*0.5-l1, n);
    double qa = norm(n)*norm(m) - dot(n,m)*dot(n,m);
    double qb = -rC * dot(n,m);
    double qc = norm(n)*norm(m) - rC*rC;
    double qd = qb*qb - qa*qc;  // qa*k^2 + 2*qb*k + qc = 0

    VP cs;
    if (qd < -EPS) return cs;
    if (EQ(qa, 0)) {
        if (!EQ(qb, 0)) cs.push_back((a+b)*0.5 - m * (qc/qb/2));
        return cs;
    }
    double t = -qb/qa;
    cs.push_back(              (a+b)*0.5 + m * (t + sqrt(max(qd, 0.0))/qa));
    if (qd > EPS) cs.push_back((a+b)*0.5 + m * (t - sqrt(max(qd, 0.0))/qa));
    return cs;
}

// 点集合を含む最小の円の中心
Point minEnclosingCircle(const VP& ps) {
    Point c;
    double move = 0.5;
    rep(i,39) {  // 2^(-39-1) \approx 0.9e-12
        rep(t,50) {
            double max = 0;
            int k = 0;
            rep (j, ps.size()) if (max < norm(ps[j]-c)) {
                max = norm(ps[j]-c);
                k = j;
            }
            c += (ps[k]-c) * move;
        }
        move /= 2;
    }
    return c;
}


/* 多角形 */

// 頂点の順序（sortやmax_elementに必要）
namespace std {
    bool operator<(const Point a, const Point b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

//多角形PSのi番目の辺
#define ps_edge(PS,i) PS[i],PS[(i+1)%PS.size()]

// 凸包
// 入力1個 -> 空
// 2個以上の全て同じ点 -> 同じもの2つ
VP convexHull(VP ps) {  // 元の点集合がソートされていいならVP&に
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    VP ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;  // 余計な点も含むなら == -1 とする
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    ch.resize(k-1);
    return ch;
}

// 凸判定。縮退を認めないならccwの判定部分を != 1 とする
// 反時計か分からなければreverse(ps)も試す（コピー渡し）
bool isCcwConvex(const VP& ps) {
    int n = ps.size();
    rep(i,n) if (ccw(ps[i], ps[(i+1) % n], ps[(i+2) % n]) == -1) return false;
    return true;
}

// 凸多角形の内部判定　O(n)
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inConvex(Point p, const VP& ps) {
    int n = ps.size();
    int dir = ccw(ps[0], ps[1], p);
    rep (i, n) {
        int ccwc = ccw(ps[i], ps[(i + 1) % n], p);
        if (!ccwc) return 2;  // 線分上に存在
        if (ccwc != dir) return 0;
    }
    return 1;
}

// 凸多角形の内部判定　O(logn)
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inCcwConvex(const VP& ps, Point p) {
    int n = ps.size();
    Point g = (ps[0] + ps[n / 3] + ps[n*2 / 3]) / 3.0;
    if (g == p) return 1;
    Point gp = p - g;

    int l = 0, r = n;
    while (l + 1 < r) {
        int mid = (l + r) / 2;
        Point gl = ps[l] - g;
        Point gm = ps[mid] - g;
        if (cross(gl, gm) > 0) {
            if (cross(gl, gp) >= 0 && cross(gm, gp) <= 0) r = mid;
            else l = mid;
        }
        else {
            if (cross(gl, gp) <= 0 && cross(gm, gp) >= 0) l = mid;
            else r = mid;
        }
    }
    r %= n;
    double cr = cross(ps[l] - p, ps[r] - p);
    return EQ(cr, 0) ? 2 : cr < 0 ? 0 : 1;
}

// 多角形の内部判定
// 点が領域内部なら1、境界上なら2、外部なら0を返す
int inPolygon(const VP& ps, Point p) {
    int n = ps.size();
    bool in = false;
    rep (i, n) {
        Point a = ps[i] - p;
        Point b = ps[(i + 1) % n] - p;
        if (EQ(cross(a,b), 0) && LE(dot(a,b), 0)) return 2;
        if (a.Y > b.Y) swap(a,b);
        if ((a.Y*b.Y < 0 || (a.Y*b.Y < EPS && b.Y > EPS)) && LE(cross(a, b), 0)) in = !in;
    }
    return in;
}


bool inPolygon(Point p,VP& ps){
    int n = ps.size();
    double sumAngle=0;
    rep(i,n){
        double t = arg(ps[(i+1)%n]-p)-arg(ps[i]-p);
        while(t > +PI) t -= 2*PI;
        while(t < -PI) t += 2*PI;
        sumAngle += t;
    }
    return (abs(sumAngle) > 0.1);
}

bool inCircle(Point p, Point c, double r){
    return abs(p-c) <= r;
}

int n,m;
// ps: n個の頂点
// cs: m個の中心

bool check(double r, VP &ps, VP &cs){
    // 全頂点が1つ以上の円に含まれている
    rep(i,n){
        bool ok = false;
        rep(j,m){
            if(inCircle(ps[i], cs[j], r)){
                ok = true;
            }
        }
        if(!ok) return false;
    }

    // 2つの中心の垂直二等分線
    rep(i,m)rep(j,i){
        Point mid = (cs[i]+cs[j])/2.0;
        double d = abs(cs[i]-mid) + 1000.0;
        VP cpcc = crosspointCC(cs[i],d, cs[j],d);
        assert((int)cpcc.size() == 2);
        rep(k,n){
            if(isecLS(cpcc[0],cpcc[1], ps[k],ps[(k+1)%n])){
                Point crossPoint = crosspointLL(cpcc[0],cpcc[1], ps[k],ps[(k+1)%n]);
                bool ok = false;
                rep(q,m){
                    if(inCircle(crossPoint, cs[q], r)) ok = true;
                }
                if(!ok) return false;
            }
        }
    }

    // 2つの円の交点が凸内なら、他の円の中に入っていたい
    rep(i,m)rep(j,i){
        VP cpcc = crosspointCC(cs[i],r, cs[j],r);
        for(auto p : cpcc)if(inPolygon(ps, p)){
            bool ok = false;
            rep(k,m)if(k!=i && k!=j){
                if(inCircle(p, cs[k], r)){
                    ok = true;
                }
            }
            if(!ok) return false;
        }
    }

    return true;
}

int main(void){
    cin>>n;
    VP ps(n);
    rep(i,n){
        double x,y;
        cin>>x>>y;
        ps[i] = Point(x,y);
    }
    ps = convexHull(ps);
    cin>>m;
    VP cs(m);
    rep(i,m){
        double x,y;
        cin>>x>>y;
        cs[i] = Point(x,y);
    }
    double l = 0, r = 1000000;
    rep(loop,100){
        double radius = (l+r)/2;
        if(check(radius, ps, cs)){
            r = radius;
        }else{
            l = radius;
        }
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 3372
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ldouble;

typedef complex<ldouble> P;
typedef complex<ldouble> V;
typedef vector<P> vecP;
typedef pair<P,P> L;
typedef pair<P,P> S;
typedef pair<P,ldouble> C;
const ldouble eps=1e-11;
const ldouble PI=acos(-1);
const ldouble PI2=PI*2.0;
 
namespace std{
  bool operator < (const P &a,const P &b){
    return (a.real()!=b.real()?
            a.real() <b.real():
            a.imag() <b.imag());
  }
};
 
V normal(V a){
  assert( abs(a)>0 );
  return a/abs(a);
}
 
ldouble Sqrt( ldouble x ){
  if(x<0)return 0;
  else return sqrt(x);
}
 
P Vector(L a){
  return a.second-a.first;
}
 
bool eq(ldouble a,ldouble b){
  return (-eps<a-b&&a-b<eps);
}
 
bool eq(P a,P b){
  return ( eq(a.real(),b.real()) && eq(a.imag(),b.imag()) );
}
 
ldouble dot(P a,P b){
  return real(b*conj(a));
}
 
ldouble cross(P a,P b){
  return imag(b*conj(a));
}
 
ldouble getArg(P a,P b){
  return arg(b*conj(a));
}
 
ldouble getTime(V a,V b){
  assert( eq(cross(a,b),0) );
  return ( dot(a,b) < 0 ? -1.0 : 1.0 ) * abs(b) / abs(a);
}
 
 
P project(P a,P b,P c){
  b-=a,c-=a;
  return a+b*real(c/b);
}
 
P reflect(P a,P b,P c){
  b-=a,c-=a;
  return a+b*conj(c/b);
}
 
int ccw(P a,P b,P c){
  P ab=b-a,ac=c-a;
  P k=ac*conj(ab);
  if(k.imag()> eps )return 1;
  if(k.imag()< -eps )return -1;
  if(k.real()< -eps )return 2;
  if(abs(ab) + eps <abs(ac))return -2;
  return 0;
}
 
bool isParallel(P a,P b){
  return eq(0, cross(a,b));
}
 
bool isParallel(S a,S b){
  return eq(0, cross( Vector(a) , Vector(b) ) );
}
 
bool onLP(L l,P p){
  P a=l.first, b=l.second;
  return eq(0, cross(b-a,p-a));
}
 
bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(b-a) , abs(a-p)+abs(b-p) );
}
 
bool isCrossSS(S s0,S s1){
  P a=s0.first, b=s0.second;
  P c=s1.first, d=s1.second;
  int f0 = ccw(a,b,c) * ccw(a,b,d);
  int f1 = ccw(c,d,a) * ccw(c,d,b);
  return (f0<=0 && f1<=0);
}
 
bool isCrossLS(L l,S s){
  P a=l.first, b=l.second;
  P c=s.first, d=s.second;
  return ( ccw(a,b,c) * ccw(a,b,d) <= 0 );
}
 
ldouble distLP(L l,P p){
  P a=l.first, b=l.second;
  ldouble res = cross(b-a,p-a) / abs(b-a);
  return abs(res);
}
 
ldouble distSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return distLP(s,p);
}
 
ldouble distSS(S s0,S s1){
  if( isCrossSS(s0,s1) )return 0;
  ldouble res0 = min( distSP( s0, s1.first ) , distSP(s0, s1.second) );
  ldouble res1 = min( distSP( s1, s0.first ) , distSP(s1, s0.second) );
  return min(res0,res1);
}
 
P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
 
  
int inPolygon(const vecP &t,P p){
  int n=t.size();
  ldouble sum=0;
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1==n?0:i+1)];
    if( ccw(a,b,p)==0 )return 1;
    sum+= getArg(a-p,b-p);
  }
  if( abs(sum) < eps )return 0;
  else return 2;
}
 
vecP andrewScan(vecP &t){
  int N=t.size(),C=0;
  vecP R(N);
  for(int i=0;i<N;i++){
    while(2<=C&&ccw(R[C-2],R[C-1],t[i])==-1)C--;
    R[C++]=t[i];
  }
  vecP res(C);
  for(int i=0;i<C;i++)res[i]=R[i];
  return res;
}
  
vecP convexHull(vecP &t){
  sort(t.begin(),t.end());
  vecP u=andrewScan(t);
  reverse(t.begin(),t.end());
  vecP l=andrewScan(t);
  for(int i=1;i+1<(int)l.size();i++)u.push_back(l[i]);
  return u;
}
 
vecP cutConvex(vecP &t,L l){
  P a=l.first, b=l.second;
  int N=t.size();
  vecP res;
  for(int i=0;i<N;i++){
    P c=t[i],d=t[(i+1)%N];
    int C=ccw(a,b,c),D=ccw(a,b,d);
    if(C!=-1)res.push_back(c);
    if(C==-D&&abs(C)==1)res.push_back(getCrossLL( l ,L(c,d) ));
  }
  return res;
}
 
P getVector(const vecP &t, int id){
  int n=t.size();
  return t[ (id+1)%n ] - t[id%n];
}
 
ldouble convex_diameter(vecP &t) {
  int n = t.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(t[i]) > imag(t[is])) is = i;
    if (imag(t[i]) < imag(t[js])) js = i;
  }
  ldouble maxd = norm(t[is]-t[js]);
  
  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
     
    if (cross( getVector(t,i), getVector(t,j)) >= 0) j = (j+1) % n;
     
    else i = (i+1) % n;
    if (norm(t[i]-t[j]) > maxd) {
      maxd = norm(t[i]-t[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}
 
bool compare_y(const P &a,const P &b){
  return a.imag() < b.imag();
}
 
ldouble closest_pair(P *a, int n){
  if(n <= 1) return 1e30;
  int m = n / 2;
  ldouble x = a[m].real();
  ldouble d = min(closest_pair(a, m), closest_pair(a + m, n - m));
  inplace_merge(a, a + m, a + n, compare_y);
  vector<P> b;
  for(int i=0;i<n;i++){
    if( abs(a[i].real() - x) >= d) continue;
    for(int j=0;j<(int)b.size();j++){
      ldouble dx = real(a[i] - b[b.size() - j - 1]);
      ldouble dy = imag(a[i] - b[b.size() - j - 1]);
      if(dy >= d) break;
      d = min(d, sqrt(dx * dx + dy * dy));
    }
    b.push_back(a[i]);
  }
  return d;
}
 
P _pool[200005];
ldouble minDist(vecP &t){
  int n=t.size();
  for(int i=0;i<n;i++)_pool[i]=t[i];
  sort( _pool, _pool+n);
  return closest_pair(_pool, n);
}
 
int getStateCC(C a,C b){
  ldouble ar=a.second, br=b.second;
  ldouble dist=abs(a.first-b.first);
  if(dist>ar+br+eps)return 4;
  if(dist>ar+br-eps)return 3;
  if(dist>abs(ar-br)+eps)return 2;
  if(dist>abs(ar-br)-eps)return 1;
  return 0;
}
 
P getCrossCC(C a,C b){
  P p1=a.first, p2=b.first;
  ldouble r1=a.second, r2=b.second;
  ldouble cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA,Sqrt(1.0-cA*cA));
}
 
P getTangentCP_(C a,P p,int flg){
  P base=a.first-p;
  ldouble ar=a.second;
  ldouble w=Sqrt(norm(base)-ar*ar);
  P s=p+base*P(w,ar * flg)/norm(base)*w;
  return s;
}
 
vector<S> getTangentCP(C a,P p){
  vector<S> res;
  P s=getTangentCP_(a,p,1);
  P t=getTangentCP_(a,p,-1);
   
  if( eq(s,t) ){
    res.push_back( S(s, s+(a.first-p)*P(0,1) ) ); 
  }else{
    res.push_back( S(p,s) );
    res.push_back( S(p,t) );
  }
  return res;
}
 
S getInTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble w=ar+br;
  ldouble h=Sqrt(norm(base)-w*w);
  P k=base*P(w,h*flg)/norm(base);
  return S(ap+k*ar,bp-k*br);
}
   
S getOutTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble h=br-ar;
   
  ldouble w=Sqrt(norm(base)-h*h);
  P k=base*P(w,h*flg)/norm(base)*P(0,flg);
  return S(ap+k*ar,bp+k*br);
}
   
vector<S> getTangentCC(C a,C b){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  vector<S> res;
  ldouble dist=abs(ap-bp);
     
  if(dist>ar+br+eps)
    res.push_back(getInTangent(a,b,1));
   
  if(dist>ar+br-eps)
    res.push_back(getInTangent(a,b,-1));
   
  if(dist>abs(ar-br)+eps)
    res.push_back(getOutTangent(a,b,1));
   
  if(dist>abs(ar-br)-eps)
    res.push_back(getOutTangent(a,b,-1));
   
  return res;
}


ldouble ex_L, ex_R;
vecP getCrossCL(C cir,L l){
  P a=l.first, b=l.second;
  ldouble cr=cir.second;
  P cp=cir.first;
   
  vecP res;
  P base=b-a,  target=project(a,b,cp);
   
  ldouble length=abs(base), h=abs(cp-target);
  base/=length;
   
  if(cr+eps<h)return res;
  ldouble w=Sqrt(cr*cr-h*h);
  ldouble L=getTime( normal(b-a) ,target-a)-w,  R=L+w*2.0;

  ex_L = L;
  ex_R = R;
  res.push_back(a+base*L);
  if( eq(L,R) )return res;
  res.push_back(a+base*R);
 
  return res;
}
 
vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    if( ccw(s.first,s.second, tmp[i] ) == 0)
      res.push_back(tmp[i]);
  return res;
}
 
ldouble getArea(C c,P a,P b){
  P cp=c.first;
  ldouble cr=c.second;
   
  P va=cp-a,  vb=cp-b;
  ldouble A=abs(va), B=abs(vb);
  ldouble f=cross(va,vb), d=distSP( S(a,b) ,cp), res=0;
   
  if( eq(0, f ) )return 0;
  if(A<cr+eps&&B<cr+eps)return f*0.5;
  if(d>cr-eps)return cr*cr*PI*getArg(va,vb)/PI2;
    
  vecP u=getCrossCS(c, S(a,b) );
   
  assert( !u.empty() );
  u.insert(u.begin(), a),  u.push_back(b);
  
  for(int i=0;i+1<(int)u.size();i++) res+=getArea(c,u[i],u[i+1]);
  return res;
}
  
ldouble getCrossArea(vecP t,C c){
  int n=t.size();
  if(n<3)return 0;
  ldouble res=0;
  for(int i=0;i<n;i++){
    P a=t[i], b=t[(i+1)%n];
    res+=getArea(c,a,b);
  }
  return res;
}
 
 
ldouble calcPolygonArea(const vecP &t){
  ldouble res=0;
  int n=t.size();
  for(int i=0;i<n;i++){
    res+= cross( t[ (i+1)%n ],t[i] );
  }
  return abs(res)*0.5;
}

bool check(const vector<P> &t,const vector<P> &u, ldouble r){
  vector<P> targets;
  for(int i=0;i<(int)t.size();i++){
    P a=t[i], b=t[ (i+1)%t.size() ];
    S seg=S(a,b);
    targets.push_back(a);
    for(int j=0;j<(int)u.size();j++){
      vector<P> tmp = getCrossCS( C(u[j],r) , seg );
      for(int k=0;k<(int)tmp.size();k++)targets.push_back(tmp[k]);
    }
  }
  for(int i=0;i<(int)u.size();i++){
    for(int j=0;j<i;j++){
      targets.push_back( getCrossCC( C(u[i],r) , C(u[j],r) ) );
      targets.push_back( getCrossCC( C(u[j],r) , C(u[i],r) ) );
    }
  }
  sort(targets.begin(), targets.end());
  targets.erase( unique( targets.begin(), targets.end() ), targets.end() );

  for(int i=0;i<(int)targets.size();i++){
    if( inPolygon( t , targets[i] ) == 0 )continue;
    ldouble mini=1e9;
    for(int j=0;j<(int)u.size();j++){
      mini=min(mini, abs( targets[i] - u[j] ) );
    }
    if( mini > r - eps )return false;
  }
  return true;
}

ldouble solve(const vector<P> &t,const vector<P> &u){
  ldouble left=0, right=1e6, mid;
  for(int i=0;i<50;i++){
    mid=(left+right)*0.5;
    if( check(t,u,mid) )right=mid;
    else left=mid;
  }
  return left;
}

int main(){

  int n;
  scanf("%d",&n);

  vector< P > t(n);
  for(int i=0;i<n;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    t[i]=P(x,y);
  }
  
  int m;
  scanf("%d",&m);
  vector< P > u(m);
  
  for(int i=0;i<m;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    u[i]=P(x,y);
  }

  printf("%.10f\n", (double)solve(t,u) );
  return 0;
  
}
accuracy: 1
time_ms: 1730
memory_kb: 9980
final_rank: 12

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef double P_type;
typedef complex<P_type> P;
const P_type P_eps = 1e-9; //整数の時はゼロ

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//内積
P_type dot(P a, P b) {
  return (a * conj(b)).real();
}

//外積
P_type cross(P a, P b) {
  return (conj(a) * b).imag();
}

//反時計回り
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < -P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < -P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* 線分abと点cの距離 */
P_type distanceSP(P a, P b, P c) {
  if ( dot(b-a, c-a) < P_eps ) return abs(c-a);
  if ( dot(a-b, c-b) < P_eps ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 直線abと点cの距離 */
P_type distanceLP(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}

/* 円の点包含判定 */
bool isContainedCP(P c, double r, P p){
  return abs(c-p) < r - P_eps; //円周上を含まない
  //return abs(c-p) < r + P_eps; //円周上を含む
}

/* 直線交差判定 */
bool isIntersectedLL(P a1, P a2, P b1, P b2){
  return abs(cross(a1-a2, b1-b2)) > P_eps;
}

/* 線分交差判定 */
bool isIntersectedSS(P a1, P a2, P b1, P b2){
  
  //線分a と 直線b
  int a = ccw(b1,b2,a1);
  int b = ccw(b1,b2,a2);
  
  //線分b と 直線a
  int c = ccw(a1,a2,b1);
  int d = ccw(a1,a2,b2);
  
  return a*b < P_eps && c*d < P_eps; // T字を除く時は -P_eps
}

/* 直線線分交差判定 */
bool isIntersectedLS(P a1, P a2, P b1, P b2){  
  int a = ccw(a1,a2,b1);
  int b = ccw(a1,a2,b2);
  
  // 直線上のとき a or b = 0 or -2 or 2
  return (a%2)*(b%2) <= 0; // T字を除く時は (** < 0)
}

/* 円交差判定 */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //外接内接を含む
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //外接内接を除く
}

/* 円直線交差判定 */
bool isIntersectedCL(P c, double r, P a1, P a2){
  return distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 円線分交差判定 */
bool isIntersectedCS(P c, double r, P a1, P a2){
  return isContainedCP(c,r,a1) &&
    isContainedCP(c,r,a2) &&
    distanceLP(a1, a2, c) < r + P_eps; //接する場合を含まない場合 - P_eps
}

/* 直線/線分交点 */
P getCrosspointLL(P a1, P a2, P b1, P b2) {
  //assert(isIntersectedLL(a1, a2, b1, b2));
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P getCrosspointSS(P a1, P a2, P b1, P b2){
  //assert(isIntersectedSS(a1, a2, b1, b2));
  return getCrosspointLL(a1, a2, b1, b2);
}

/* 円交点 */
pair<P,P> getCrosspointCC(P c1, P_type r1, P c2, P_type r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist*dist - r2*r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}

/* 円線分交点 */
pair<P,P> getCrosspointCS(P c, double r, P a1, P a2){
  //assert(isIntersectedCS(c1, r1, c2, r2));
  
  P base1 = a2 - a1;
  P proj = a1 + base1 * dot(c - a1, base1) / norm(base1); //射影
  P e = (a2 - a1) / abs(a2 - a1);
  P base2 = sqrt(r*r - norm(proj - c));
  return {proj + e*base2, proj - e*base2};
}

/* 多角形-点包含 */
bool iscontainedPolyP(vector<P> &g, P p){
  int n = g.size();
  bool f = false;
  for(int i=0;i<n;i++){
    P a = g[i] - p, b = g[(i+1)%n] - p;
    if(abs(cross(a,b)) < P_eps && dot(a,b) < P_eps) return true; //辺上
    if(a.imag() > b.imag()) swap(a,b);
    if(a.imag() < P_eps && P_eps < b.imag() && cross(a,b) > P_eps) f = !f;
  }
  return f; //内部 or 外部
}

/* 射影(直線abとpからの垂線との交点) */
P getProject(P a, P b, P p){
  P base = b - a;
  return a + base * dot(p - a, base) / norm(base);
}

/* 反射(直線abを対称軸としたpの線対称の位置) */
P getReflection(P a, P b, P p){
  return p + (getProject(a, b, p) - p) * (P_type)2.0;
}


int main(){
  int n, m, x, y;
  P pxy[101], cxy[101];
  vector<P> pol;

  scanf("%d", &n);
  
  for(int i=0;i<n;i++){
    scanf("%d%d", &x, &y);
    pxy[i] = P(x, y);
    pol.push_back(pxy[i]);
  }
  pxy[n] = pxy[0];
  

  scanf("%d", &m);
  
  for(int i=0;i<m;i++){
    scanf("%d%d", &x, &y);
    cxy[i] = P(x, y);

  }

  P_type l = 0, r = 1e6;

  while(abs(l-r) > 1e-6){
    P_type R = (l+r)/2;
    vector<P> vec; 
    
    for(int i=0;i<m;i++){
      for(int j=i+1;j<m;j++){
        if(!isIntersectedCC(cxy[i], R, cxy[j], R)) continue;
        auto gc = getCrosspointCC(cxy[i], R, cxy[j], R);

        auto e = (gc.first - gc.second) / abs(gc.first - gc.second) * (P_type)1e-7;

        vec.push_back(gc.first + e * (P_type)1);
        vec.push_back(gc.first + e * (P_type)-1);
        vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    for(int i=0;i<m;i++){
      for(int j=0;j<n;j++){
        auto gc = getCrosspointCS(cxy[i], R, pxy[j], pxy[j+1]);

        auto e = (pxy[j] - pxy[j+1]) / abs(pxy[j] - pxy[j+1]) * (P_type)1e-7;

        vec.push_back(gc.first + e * (P_type)1);
        vec.push_back(gc.first + e * (P_type)-1);
        vec.push_back(gc.second + e * (P_type)1);
        vec.push_back(gc.second + e * (P_type)-1);
      }
    }

    bool res = true;
    
    for(int i=0;i<vec.size() && res;i++){
      if(iscontainedPolyP(pol, vec[i])){

        bool f = false;
        for(int j=0;j<m && !f;j++){
          f |= isContainedCP(cxy[j], R, vec[i]);
        }

        res &= f;
      }
    }

    if(res){
      r = R;
    }else{
      l = R;
    }
  }

  printf("%.10lf\n", (double)l);
  
  
  return 0;
}
accuracy: 0.38095238095238093
time_ms: 30
memory_kb: 3768
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef double Real;
typedef complex<Real> P;

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define FORR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)

#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))

#define MOD 1000000007
#define eps 1e-8

int n,m;
P cvx[125];
P pts[125];

Real cross(P a, P b){
  return imag(conj(a)*b);
}
Real dot(P a, P b){
  return real(conj(a)*b);
}

bool inner(P p){
  P g = (cvx[0] + cvx[n/3] + cvx[2*n/3]) / 3.0;
  // g += P(1e-7, 1e-7);
  int a = 0, b = n;
  while(a+1<b){
    int c = (a+b)/2;
    if(cross(cvx[a]-g, cvx[c]-g)>0){
      if(cross(cvx[a]-g, p-g)>0 && cross(cvx[c]-g, p-g)<0) b=c;
      else a=c;
    }else{
      if(cross(cvx[a]-g, p-g)<0 && cross(cvx[c]-g, p-g)>0) a=c;
      else b=c;
    }
  }
  b %= n;
  if(cross(cvx[a]-p, cvx[b]-p)<-eps) return false;
  return true;
}

bool inner2(P p){
  bool in = false;
  REP(i,n){
    P a = cvx[i]-p;
    P b = cvx[(i+1)%n]-p;
    if(imag(a)>imag(b))swap(a,b);
    if(imag(a)<=0 && 0<imag(b)){
      if(cross(a,b)<0)in = !in;
    }
    if(abs(cross(a,b))<eps && dot(a,b)<=0)return true;
  }
  return in;
}

int main(){
  scanf("%d",&n);
  REP(i,n){
    Real x,y;
    scanf("%lf%lf",&x,&y);
    cvx[i] = P(x,y);
  }
  scanf("%d",&m);
  REP(i,m){
    Real x,y;
    scanf("%lf%lf",&x,&y);
    pts[i] = P(x,y);
  }
  vector<P> po;
  const Real PI = 4.0*atan(1.0);

  REP(i,n)po.push_back(cvx[i]);

  REP(i,m)REP(j,i){
    P a = pts[i], b = pts[j];
    P s1 = (a+b)/2.0;
    P d1 = (b-a)*exp(P(0,PI/2.0));
    REP(ii,n){
      P x = cvx[ii], y = cvx[(ii+1)%n];
      P s2 = x;
      P d2 = y-x;
      if(cross(d1,s2-s1)*cross(d1,s2+d2-s1) >= eps)continue;
      if(abs(cross(d2,d1))<eps)continue;
      P o = s1 + d1*cross(d2, s2-s1)/cross(d2, d1);
      // #define X real()
      // #define Y imag()
      // if(x.X <= y.X && (o.X < x.X-eps || o.X > y.X+eps))continue;
      // if(x.X >= y.X && (o.X > x.X+eps || o.X < y.X-eps))continue;
      // if(x.Y <= y.X && (o.Y < x.Y-eps || o.Y > y.Y+eps))continue;
      // if(x.Y >= y.X && (o.Y > x.Y+eps || o.Y < y.Y-eps))continue;
      po.push_back(o);
    }
  }

  REP(i,m)REP(j,i)REP(k,j){
    P a = pts[i], b = pts[j], c = pts[k];
    if(abs(cross(b-a,c-a))<eps)continue;
    P ab = (a+b)/2.0;
    P ac = (a+c)/2.0;
    P abd = (b-a)*exp(P(0,PI/2.0));
    P acd = (c-a)*exp(P(0,PI/2.0));
    P o = ab + abd * cross(acd, ac-ab) / cross(acd, abd);
    if(inner2(o))po.push_back(o);
  }

  Real ans = 0.0;
  REP(i,po.size()){
    P o = po[i];
    Real tmp = 1e18;
    REP(ii,m){
      CHMIN(tmp, abs(pts[ii]-o));
    }
    CHMAX(ans, tmp);
  }
  printf("%.9f\n",ans);
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 4992
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ldouble;

typedef complex<ldouble> P;
typedef complex<ldouble> V;
typedef vector<P> vecP;
typedef pair<P,P> L;
typedef pair<P,P> S;
typedef pair<P,ldouble> C;
const ldouble eps=1e-11;
const ldouble PI=acos(-1);
const ldouble PI2=PI*2.0;
 
namespace std{
  bool operator < (const P &a,const P &b){
    return (a.real()!=b.real()?
            a.real() <b.real():
            a.imag() <b.imag());
  }
};
 
V normal(V a){
  assert( abs(a)>0 );
  return a/abs(a);
}
 
ldouble Sqrt( ldouble x ){
  if(x<0)return 0;
  else return sqrt(x);
}
 
P Vector(L a){
  return a.second-a.first;
}
 
bool eq(ldouble a,ldouble b){
  return (-eps<a-b&&a-b<eps);
}
 
bool eq(P a,P b){
  return ( eq(a.real(),b.real()) && eq(a.imag(),b.imag()) );
}
 
ldouble dot(P a,P b){
  return real(b*conj(a));
}
 
ldouble cross(P a,P b){
  return imag(b*conj(a));
}
 
ldouble getArg(P a,P b){
  return arg(b*conj(a));
}
 
ldouble getTime(V a,V b){
  assert( eq(cross(a,b),0) );
  return ( dot(a,b) < 0 ? -1.0 : 1.0 ) * abs(b) / abs(a);
}
 
 
P project(P a,P b,P c){
  b-=a,c-=a;
  return a+b*real(c/b);
}
 
P reflect(P a,P b,P c){
  b-=a,c-=a;
  return a+b*conj(c/b);
}
 
int ccw(P a,P b,P c){
  P ab=b-a,ac=c-a;
  P k=ac*conj(ab);
  if(k.imag()> eps )return 1;
  if(k.imag()< -eps )return -1;
  if(k.real()< -eps )return 2;
  if(abs(ab) + eps <abs(ac))return -2;
  return 0;
}
 
bool isParallel(P a,P b){
  return eq(0, cross(a,b));
}
 
bool isParallel(S a,S b){
  return eq(0, cross( Vector(a) , Vector(b) ) );
}
 
bool onLP(L l,P p){
  P a=l.first, b=l.second;
  return eq(0, cross(b-a,p-a));
}
 
bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(b-a) , abs(a-p)+abs(b-p) );
}
 
bool isCrossSS(S s0,S s1){
  P a=s0.first, b=s0.second;
  P c=s1.first, d=s1.second;
  int f0 = ccw(a,b,c) * ccw(a,b,d);
  int f1 = ccw(c,d,a) * ccw(c,d,b);
  return (f0<=0 && f1<=0);
}
 
bool isCrossLS(L l,S s){
  P a=l.first, b=l.second;
  P c=s.first, d=s.second;
  return ( ccw(a,b,c) * ccw(a,b,d) <= 0 );
}
 
ldouble distLP(L l,P p){
  P a=l.first, b=l.second;
  ldouble res = cross(b-a,p-a) / abs(b-a);
  return abs(res);
}
 
ldouble distSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return distLP(s,p);
}
 
ldouble distSS(S s0,S s1){
  if( isCrossSS(s0,s1) )return 0;
  ldouble res0 = min( distSP( s0, s1.first ) , distSP(s0, s1.second) );
  ldouble res1 = min( distSP( s1, s0.first ) , distSP(s1, s0.second) );
  return min(res0,res1);
}
 
P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
 
  
int inPolygon(vecP &t,P p){
  int n=t.size();
  ldouble sum=0;
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1==n?0:i+1)];
    if( ccw(a,b,p)==0 )return 1;
    sum+= getArg(a-p,b-p);
  }
  if( abs(sum) < eps )return 0;
  else return 2;
}
 
vecP andrewScan(vecP &t){
  int N=t.size(),C=0;
  vecP R(N);
  for(int i=0;i<N;i++){
    while(2<=C&&ccw(R[C-2],R[C-1],t[i])==-1)C--;
    R[C++]=t[i];
  }
  vecP res(C);
  for(int i=0;i<C;i++)res[i]=R[i];
  return res;
}
  
vecP convexHull(vecP &t){
  sort(t.begin(),t.end());
  vecP u=andrewScan(t);
  reverse(t.begin(),t.end());
  vecP l=andrewScan(t);
  for(int i=1;i+1<(int)l.size();i++)u.push_back(l[i]);
  return u;
}
 
vecP cutConvex(vecP &t,L l){
  P a=l.first, b=l.second;
  int N=t.size();
  vecP res;
  for(int i=0;i<N;i++){
    P c=t[i],d=t[(i+1)%N];
    int C=ccw(a,b,c),D=ccw(a,b,d);
    if(C!=-1)res.push_back(c);
    if(C==-D&&abs(C)==1)res.push_back(getCrossLL( l ,L(c,d) ));
  }
  return res;
}
 
P getVector(const vecP &t, int id){
  int n=t.size();
  return t[ (id+1)%n ] - t[id%n];
}
 
ldouble convex_diameter(vecP &t) {
  int n = t.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(t[i]) > imag(t[is])) is = i;
    if (imag(t[i]) < imag(t[js])) js = i;
  }
  ldouble maxd = norm(t[is]-t[js]);
  
  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
     
    if (cross( getVector(t,i), getVector(t,j)) >= 0) j = (j+1) % n;
     
    else i = (i+1) % n;
    if (norm(t[i]-t[j]) > maxd) {
      maxd = norm(t[i]-t[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}
 
bool compare_y(const P &a,const P &b){
  return a.imag() < b.imag();
}
 
ldouble closest_pair(P *a, int n){
  if(n <= 1) return 1e30;
  int m = n / 2;
  ldouble x = a[m].real();
  ldouble d = min(closest_pair(a, m), closest_pair(a + m, n - m));
  inplace_merge(a, a + m, a + n, compare_y);
  vector<P> b;
  for(int i=0;i<n;i++){
    if( abs(a[i].real() - x) >= d) continue;
    for(int j=0;j<(int)b.size();j++){
      ldouble dx = real(a[i] - b[b.size() - j - 1]);
      ldouble dy = imag(a[i] - b[b.size() - j - 1]);
      if(dy >= d) break;
      d = min(d, sqrt(dx * dx + dy * dy));
    }
    b.push_back(a[i]);
  }
  return d;
}
 
P _pool[200005];
ldouble minDist(vecP &t){
  int n=t.size();
  for(int i=0;i<n;i++)_pool[i]=t[i];
  sort( _pool, _pool+n);
  return closest_pair(_pool, n);
}
 
int getStateCC(C a,C b){
  ldouble ar=a.second, br=b.second;
  ldouble dist=abs(a.first-b.first);
  if(dist>ar+br+eps)return 4;
  if(dist>ar+br-eps)return 3;
  if(dist>abs(ar-br)+eps)return 2;
  if(dist>abs(ar-br)-eps)return 1;
  return 0;
}
 
P getCrossCC(C a,C b){
  P p1=a.first, p2=b.first;
  ldouble r1=a.second, r2=b.second;
  ldouble cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA,Sqrt(1.0-cA*cA));
}
 
P getTangentCP_(C a,P p,int flg){
  P base=a.first-p;
  ldouble ar=a.second;
  ldouble w=Sqrt(norm(base)-ar*ar);
  P s=p+base*P(w,ar * flg)/norm(base)*w;
  return s;
}
 
vector<S> getTangentCP(C a,P p){
  vector<S> res;
  P s=getTangentCP_(a,p,1);
  P t=getTangentCP_(a,p,-1);
   
  if( eq(s,t) ){
    res.push_back( S(s, s+(a.first-p)*P(0,1) ) ); 
  }else{
    res.push_back( S(p,s) );
    res.push_back( S(p,t) );
  }
  return res;
}
 
S getInTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble w=ar+br;
  ldouble h=Sqrt(norm(base)-w*w);
  P k=base*P(w,h*flg)/norm(base);
  return S(ap+k*ar,bp-k*br);
}
   
S getOutTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble h=br-ar;
   
  ldouble w=Sqrt(norm(base)-h*h);
  P k=base*P(w,h*flg)/norm(base)*P(0,flg);
  return S(ap+k*ar,bp+k*br);
}
   
vector<S> getTangentCC(C a,C b){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  vector<S> res;
  ldouble dist=abs(ap-bp);
     
  if(dist>ar+br+eps)
    res.push_back(getInTangent(a,b,1));
   
  if(dist>ar+br-eps)
    res.push_back(getInTangent(a,b,-1));
   
  if(dist>abs(ar-br)+eps)
    res.push_back(getOutTangent(a,b,1));
   
  if(dist>abs(ar-br)-eps)
    res.push_back(getOutTangent(a,b,-1));
   
  return res;
}


ldouble ex_L, ex_R;
vecP getCrossCL(C cir,L l){
  P a=l.first, b=l.second;
  ldouble cr=cir.second;
  P cp=cir.first;
   
  vecP res;
  P base=b-a,  target=project(a,b,cp);
   
  ldouble length=abs(base), h=abs(cp-target);
  base/=length;
   
  if(cr+eps<h)return res;
  ldouble w=Sqrt(cr*cr-h*h);
  ldouble L=getTime( normal(b-a) ,target-a)-w,  R=L+w*2.0;

  ex_L = L;
  ex_R = R;
  res.push_back(a+base*L);
  if( eq(L,R) )return res;
  res.push_back(a+base*R);
 
  return res;
}
 
vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    if( ccw(s.first,s.second, tmp[i] ) == 0)
      res.push_back(tmp[i]);
  return res;
}
 
ldouble getArea(C c,P a,P b){
  P cp=c.first;
  ldouble cr=c.second;
   
  P va=cp-a,  vb=cp-b;
  ldouble A=abs(va), B=abs(vb);
  ldouble f=cross(va,vb), d=distSP( S(a,b) ,cp), res=0;
   
  if( eq(0, f ) )return 0;
  if(A<cr+eps&&B<cr+eps)return f*0.5;
  if(d>cr-eps)return cr*cr*PI*getArg(va,vb)/PI2;
    
  vecP u=getCrossCS(c, S(a,b) );
   
  assert( !u.empty() );
  u.insert(u.begin(), a),  u.push_back(b);
  
  for(int i=0;i+1<(int)u.size();i++) res+=getArea(c,u[i],u[i+1]);
  return res;
}
  
ldouble getCrossArea(vecP t,C c){
  int n=t.size();
  if(n<3)return 0;
  ldouble res=0;
  for(int i=0;i<n;i++){
    P a=t[i], b=t[(i+1)%n];
    res+=getArea(c,a,b);
  }
  return res;
}
 
 
ldouble calcPolygonArea(const vecP &t){
  ldouble res=0;
  int n=t.size();
  for(int i=0;i<n;i++){
    res+= cross( t[ (i+1)%n ],t[i] );
  }
  return abs(res)*0.5;
}


bool check2(const vector<P> &u,ldouble r, S s){
  typedef pair<ldouble,ldouble>  Pair;
  vector< Pair > t,nt;
  
  for(int i=0;i<(int)u.size();i++){
    vector< P > tmp = getCrossCL( C(u[i] , r) , s );
    t.push_back(Pair( ex_L, ex_R ));
  }
  sort( t.begin(), t.end() );
  for(int i=0;i<(int)t.size();i++){
    if(i+1<(int)t.size() && t[i].second > t[i+1].first-eps ){
      t[i+1].first=min(t[i+1].first, t[i].first );
      t[i+1].second=max(t[i+1].second, t[i].second );
    }else{
      nt.push_back(t[i]);
    }
  }
  
  for(int i=0;i< (int)nt.size();i++)
    if(nt[i].first < eps && nt[i].second > abs(s.second-s.first)-eps )
      return true;
  
  return false;
}

bool check(const vector<S> &t,const vector<P> &u, ldouble r){
  for(int i=0;i<(int)t.size();i++){
    
    if( check2(u,r,t[i]) ){
      continue;
    }else{
      return false;
    }
  }
  return true;
}

ldouble solve(const vector<S> &t,const vector<P> &u){
  ldouble left=0, right=1e6, mid;
  for(int i=0;i<50;i++){
    mid=(left+right)*0.5;
    if( check(t,u,mid) )right=mid;
    else left=mid;
  }
  return left;
}

int main(){

  int n;
  scanf("%d",&n);

  P cp=P(0,0);
  vector< P > t(n), t2;
  for(int i=0;i<n;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    t[i]=P(x,y);
    cp+=t[i];
  }
  cp /= (ldouble)n;
  
  
  //  cout<< (double)cp.real() <<' '<< (double)cp.imag() <<endl;
  vector<  vector< P >  > G(n);
  for(int i=0;i<n;i++){
    
    P base=t[ (i+1)%n ] - t[i];

    int Cnt=70/n+5;
    // Cnt * Cnt * n*n <= 900
    // Cnt*n ^2 <= 30^2
    // Cnt*n <= 30
    // Cnt = 30/n
    for(int j=1;j< Cnt ;j++)
      G[i].push_back(  t[i] + base*( (ldouble)j/ (ldouble)Cnt ) );
  }
  
  int m;
  scanf("%d",&m);
  vector< P > u(m);
  for(int i=0;i<m;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    u[i]=P(x,y);
  }
  
  vector< S > w;
  for(int i=0;i<n;i++){
    w.push_back( S(t[i], t[ (i+1)%n ] ) );
    w.push_back( S(t[i], cp ) );
    for(P a:G[i])
      w.push_back( S(a, cp ) );
    //    cout<<w.size()<<endl;
    for(int j=0;j<i;j++){
      for(P a:G[i])
        for(P b:G[j])
          w.push_back( S(a,b) );
    }
  }

  printf("%.10f\n", (double)solve(w,u) );
  return 0;
  
}
/*

bool check(const vector<S> &t,const vector<P> &u, ldouble r){
  vector<P> targets;
  for(int i=0;i<(int)t.size();i++){
    for(int j=0;j<(int)u.size();j++){
      vector<P> tmp = getCrossCS( C(u[j],r), t[i] );
      for(int k=0;k<(int)tmp.size();k++)targets.push_back(tmp[k]);
      targets.push_back(t[i].first);
      targets.push_back(t[i].second);
    }
  }
  sort( targets.begin(), targets.end() );
  targets.erase( unique(targets.begin(), targets.end() ), targets.end() );
  for(int i=0;i<(int)targets.size();i++){

    ldouble mini=1e9;
    for(int j=0;j<(int)u.size();j++){
      ldouble dist=abs(targets[i]-u[j]);
      mini=min(mini,dist);
    }
    if( mini > r - eps )return false;
  }
  return true;
}

*/
accuracy: 0.16666666666666666
time_ms: 1030
memory_kb: 3460
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ldouble;

typedef complex<ldouble> P;
typedef complex<ldouble> V;
typedef vector<P> vecP;
typedef pair<P,P> L;
typedef pair<P,P> S;
typedef pair<P,ldouble> C;
const ldouble eps=1e-11;
const ldouble PI=acos(-1);
const ldouble PI2=PI*2.0;
 
namespace std{
  bool operator < (const P &a,const P &b){
    return (a.real()!=b.real()?
            a.real() <b.real():
            a.imag() <b.imag());
  }
};
 
V normal(V a){
  assert( abs(a)>0 );
  return a/abs(a);
}
 
ldouble Sqrt( ldouble x ){
  if(x<0)return 0;
  else return sqrt(x);
}
 
P Vector(L a){
  return a.second-a.first;
}
 
bool eq(ldouble a,ldouble b){
  return (-eps<a-b&&a-b<eps);
}
 
bool eq(P a,P b){
  return ( eq(a.real(),b.real()) && eq(a.imag(),b.imag()) );
}
 
ldouble dot(P a,P b){
  return real(b*conj(a));
}
 
ldouble cross(P a,P b){
  return imag(b*conj(a));
}
 
ldouble getArg(P a,P b){
  return arg(b*conj(a));
}
 
ldouble getTime(V a,V b){
  assert( eq(cross(a,b),0) );
  return ( dot(a,b) < 0 ? -1.0 : 1.0 ) * abs(b) / abs(a);
}
 
 
P project(P a,P b,P c){
  b-=a,c-=a;
  return a+b*real(c/b);
}
 
P reflect(P a,P b,P c){
  b-=a,c-=a;
  return a+b*conj(c/b);
}
 
int ccw(P a,P b,P c){
  P ab=b-a,ac=c-a;
  P k=ac*conj(ab);
  if(k.imag()> eps )return 1;
  if(k.imag()< -eps )return -1;
  if(k.real()< -eps )return 2;
  if(abs(ab) + eps <abs(ac))return -2;
  return 0;
}
 
bool isParallel(P a,P b){
  return eq(0, cross(a,b));
}
 
bool isParallel(S a,S b){
  return eq(0, cross( Vector(a) , Vector(b) ) );
}
 
bool onLP(L l,P p){
  P a=l.first, b=l.second;
  return eq(0, cross(b-a,p-a));
}
 
bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(b-a) , abs(a-p)+abs(b-p) );
}
 
bool isCrossSS(S s0,S s1){
  P a=s0.first, b=s0.second;
  P c=s1.first, d=s1.second;
  int f0 = ccw(a,b,c) * ccw(a,b,d);
  int f1 = ccw(c,d,a) * ccw(c,d,b);
  return (f0<=0 && f1<=0);
}
 
bool isCrossLS(L l,S s){
  P a=l.first, b=l.second;
  P c=s.first, d=s.second;
  return ( ccw(a,b,c) * ccw(a,b,d) <= 0 );
}
 
ldouble distLP(L l,P p){
  P a=l.first, b=l.second;
  ldouble res = cross(b-a,p-a) / abs(b-a);
  return abs(res);
}
 
ldouble distSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return distLP(s,p);
}
 
ldouble distSS(S s0,S s1){
  if( isCrossSS(s0,s1) )return 0;
  ldouble res0 = min( distSP( s0, s1.first ) , distSP(s0, s1.second) );
  ldouble res1 = min( distSP( s1, s0.first ) , distSP(s1, s0.second) );
  return min(res0,res1);
}
 
P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
 
  
int inPolygon(vecP &t,P p){
  int n=t.size();
  ldouble sum=0;
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1==n?0:i+1)];
    if( ccw(a,b,p)==0 )return 1;
    sum+= getArg(a-p,b-p);
  }
  if( abs(sum) < eps )return 0;
  else return 2;
}
 
vecP andrewScan(vecP &t){
  int N=t.size(),C=0;
  vecP R(N);
  for(int i=0;i<N;i++){
    while(2<=C&&ccw(R[C-2],R[C-1],t[i])==-1)C--;
    R[C++]=t[i];
  }
  vecP res(C);
  for(int i=0;i<C;i++)res[i]=R[i];
  return res;
}
  
vecP convexHull(vecP &t){
  sort(t.begin(),t.end());
  vecP u=andrewScan(t);
  reverse(t.begin(),t.end());
  vecP l=andrewScan(t);
  for(int i=1;i+1<(int)l.size();i++)u.push_back(l[i]);
  return u;
}
 
vecP cutConvex(vecP &t,L l){
  P a=l.first, b=l.second;
  int N=t.size();
  vecP res;
  for(int i=0;i<N;i++){
    P c=t[i],d=t[(i+1)%N];
    int C=ccw(a,b,c),D=ccw(a,b,d);
    if(C!=-1)res.push_back(c);
    if(C==-D&&abs(C)==1)res.push_back(getCrossLL( l ,L(c,d) ));
  }
  return res;
}
 
P getVector(const vecP &t, int id){
  int n=t.size();
  return t[ (id+1)%n ] - t[id%n];
}
 
ldouble convex_diameter(vecP &t) {
  int n = t.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(t[i]) > imag(t[is])) is = i;
    if (imag(t[i]) < imag(t[js])) js = i;
  }
  ldouble maxd = norm(t[is]-t[js]);
  
  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
     
    if (cross( getVector(t,i), getVector(t,j)) >= 0) j = (j+1) % n;
     
    else i = (i+1) % n;
    if (norm(t[i]-t[j]) > maxd) {
      maxd = norm(t[i]-t[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}
 
bool compare_y(const P &a,const P &b){
  return a.imag() < b.imag();
}
 
ldouble closest_pair(P *a, int n){
  if(n <= 1) return 1e30;
  int m = n / 2;
  ldouble x = a[m].real();
  ldouble d = min(closest_pair(a, m), closest_pair(a + m, n - m));
  inplace_merge(a, a + m, a + n, compare_y);
  vector<P> b;
  for(int i=0;i<n;i++){
    if( abs(a[i].real() - x) >= d) continue;
    for(int j=0;j<(int)b.size();j++){
      ldouble dx = real(a[i] - b[b.size() - j - 1]);
      ldouble dy = imag(a[i] - b[b.size() - j - 1]);
      if(dy >= d) break;
      d = min(d, sqrt(dx * dx + dy * dy));
    }
    b.push_back(a[i]);
  }
  return d;
}
 
P _pool[200005];
ldouble minDist(vecP &t){
  int n=t.size();
  for(int i=0;i<n;i++)_pool[i]=t[i];
  sort( _pool, _pool+n);
  return closest_pair(_pool, n);
}
 
int getStateCC(C a,C b){
  ldouble ar=a.second, br=b.second;
  ldouble dist=abs(a.first-b.first);
  if(dist>ar+br+eps)return 4;
  if(dist>ar+br-eps)return 3;
  if(dist>abs(ar-br)+eps)return 2;
  if(dist>abs(ar-br)-eps)return 1;
  return 0;
}
 
P getCrossCC(C a,C b){
  P p1=a.first, p2=b.first;
  ldouble r1=a.second, r2=b.second;
  ldouble cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA,Sqrt(1.0-cA*cA));
}
 
P getTangentCP_(C a,P p,int flg){
  P base=a.first-p;
  ldouble ar=a.second;
  ldouble w=Sqrt(norm(base)-ar*ar);
  P s=p+base*P(w,ar * flg)/norm(base)*w;
  return s;
}
 
vector<S> getTangentCP(C a,P p){
  vector<S> res;
  P s=getTangentCP_(a,p,1);
  P t=getTangentCP_(a,p,-1);
   
  if( eq(s,t) ){
    res.push_back( S(s, s+(a.first-p)*P(0,1) ) ); 
  }else{
    res.push_back( S(p,s) );
    res.push_back( S(p,t) );
  }
  return res;
}
 
S getInTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble w=ar+br;
  ldouble h=Sqrt(norm(base)-w*w);
  P k=base*P(w,h*flg)/norm(base);
  return S(ap+k*ar,bp-k*br);
}
   
S getOutTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble h=br-ar;
   
  ldouble w=Sqrt(norm(base)-h*h);
  P k=base*P(w,h*flg)/norm(base)*P(0,flg);
  return S(ap+k*ar,bp+k*br);
}
   
vector<S> getTangentCC(C a,C b){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  vector<S> res;
  ldouble dist=abs(ap-bp);
     
  if(dist>ar+br+eps)
    res.push_back(getInTangent(a,b,1));
   
  if(dist>ar+br-eps)
    res.push_back(getInTangent(a,b,-1));
   
  if(dist>abs(ar-br)+eps)
    res.push_back(getOutTangent(a,b,1));
   
  if(dist>abs(ar-br)-eps)
    res.push_back(getOutTangent(a,b,-1));
   
  return res;
}
 
 
vecP getCrossCL(C cir,L l){
  P a=l.first, b=l.second;
  ldouble cr=cir.second;
  P cp=cir.first;
   
  vecP res;
  P base=b-a,  target=project(a,b,cp);
   
  ldouble length=abs(base), h=abs(cp-target);
  base/=length;
   
  if(cr+eps<h)return res;
  ldouble w=Sqrt(cr*cr-h*h);
  ldouble L=getTime( normal(b-a) ,target-a)-w,  R=L+w*2.0;
   
  res.push_back(a+base*L);
  if( eq(L,R) )return res;
  res.push_back(a+base*R);
 
  return res;
}
 
vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    if( ccw(s.first,s.second, tmp[i] ) == 0)
      res.push_back(tmp[i]);
  
  return res;
}
 
ldouble getArea(C c,P a,P b){
  P cp=c.first;
  ldouble cr=c.second;
   
  P va=cp-a,  vb=cp-b;
  ldouble A=abs(va), B=abs(vb);
  ldouble f=cross(va,vb), d=distSP( S(a,b) ,cp), res=0;
   
  if( eq(0, f ) )return 0;
  if(A<cr+eps&&B<cr+eps)return f*0.5;
  if(d>cr-eps)return cr*cr*PI*getArg(va,vb)/PI2;
    
  vecP u=getCrossCS(c, S(a,b) );
   
  assert( !u.empty() );
  u.insert(u.begin(), a),  u.push_back(b);
  
  for(int i=0;i+1<(int)u.size();i++) res+=getArea(c,u[i],u[i+1]);
  return res;
}
  
ldouble getCrossArea(vecP t,C c){
  int n=t.size();
  if(n<3)return 0;
  ldouble res=0;
  for(int i=0;i<n;i++){
    P a=t[i], b=t[(i+1)%n];
    res+=getArea(c,a,b);
  }
  return res;
}
 
 
ldouble calcPolygonArea(const vecP &t){
  ldouble res=0;
  int n=t.size();
  for(int i=0;i<n;i++){
    res+= cross( t[ (i+1)%n ],t[i] );
  }
  return abs(res)*0.5;
}


bool check(const vector<S> &t,const vector<P> &u, ldouble r){
  vector<P> targets;
  for(int i=0;i<(int)t.size();i++){
    for(int j=0;j<(int)u.size();j++){
      vector<P> tmp = getCrossCS( C(u[j],r), t[i] );
      for(int k=0;k<(int)tmp.size();k++)targets.push_back(tmp[k]);
      targets.push_back(t[i].first);
      targets.push_back(t[i].second);
    }
  }
  sort( targets.begin(), targets.end() );
  targets.erase( unique(targets.begin(), targets.end() ), targets.end() );
  for(int i=0;i<(int)targets.size();i++){

    ldouble mini=1e9;
    for(int j=0;j<(int)u.size();j++){
      ldouble dist=abs(targets[i]-u[j]);
      mini=min(mini,dist);
    }
    if( mini > r - eps )return false;
  }
  return true;
}

ldouble solve(const vector<S> &t,const vector<P> &u){
  ldouble left=0, right=1e6, mid;
  for(int i=0;i<50;i++){
    mid=(left+right)*0.5;
    if( check(t,u,mid) )right=mid;
    else left=mid;
  }
  return left;
}

int main(){
  
  int n;
  scanf("%d",&n);
  P cp=P(0,0);
  vector< P > t(n);
  for(int i=0;i<n;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    t[i]=P(x,y);
    cp+=t[i];
  }
  
  t.push_back( cp / (ldouble)n );
  
  
  int m;
  scanf("%d",&m);
  vector< P > u(m);
  for(int i=0;i<m;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    u[i]=P(x,y);
  }

  vector< S > w;
  for(int i=0;i<n;i++){
    for(int j=0;j<i;j++){
      w.push_back( S(t[i],t[j]) );
    }
  }
  
  printf("%.10f\n", (double)solve(w,u) );
  return 0;
  
}
accuracy: 0.023809523809523808
time_ms: 10
memory_kb: 9536
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ldouble;

typedef complex<ldouble> P;
typedef complex<ldouble> V;
typedef vector<P> vecP;
typedef pair<P,P> L;
typedef pair<P,P> S;
typedef pair<P,ldouble> C;
const ldouble eps=1e-11;
const ldouble PI=acos(-1);
const ldouble PI2=PI*2.0;
 
namespace std{
  bool operator < (const P &a,const P &b){
    return (a.real()!=b.real()?
            a.real() <b.real():
            a.imag() <b.imag());
  }
};
 
V normal(V a){
  assert( abs(a)>0 );
  return a/abs(a);
}
 
ldouble Sqrt( ldouble x ){
  if(x<0)return 0;
  else return sqrt(x);
}
 
P Vector(L a){
  return a.second-a.first;
}
 
bool eq(ldouble a,ldouble b){
  return (-eps<a-b&&a-b<eps);
}
 
bool eq(P a,P b){
  return ( eq(a.real(),b.real()) && eq(a.imag(),b.imag()) );
}
 
ldouble dot(P a,P b){
  return real(b*conj(a));
}
 
ldouble cross(P a,P b){
  return imag(b*conj(a));
}
 
ldouble getArg(P a,P b){
  return arg(b*conj(a));
}
 
ldouble getTime(V a,V b){
  assert( eq(cross(a,b),0) );
  return ( dot(a,b) < 0 ? -1.0 : 1.0 ) * abs(b) / abs(a);
}
 
 
P project(P a,P b,P c){
  b-=a,c-=a;
  return a+b*real(c/b);
}
 
P reflect(P a,P b,P c){
  b-=a,c-=a;
  return a+b*conj(c/b);
}
 
int ccw(P a,P b,P c){
  P ab=b-a,ac=c-a;
  P k=ac*conj(ab);
  if(k.imag()> eps )return 1;
  if(k.imag()< -eps )return -1;
  if(k.real()< -eps )return 2;
  if(abs(ab) + eps <abs(ac))return -2;
  return 0;
}
 
bool isParallel(P a,P b){
  return eq(0, cross(a,b));
}
 
bool isParallel(S a,S b){
  return eq(0, cross( Vector(a) , Vector(b) ) );
}
 
bool onLP(L l,P p){
  P a=l.first, b=l.second;
  return eq(0, cross(b-a,p-a));
}
 
bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(b-a) , abs(a-p)+abs(b-p) );
}
 
bool isCrossSS(S s0,S s1){
  P a=s0.first, b=s0.second;
  P c=s1.first, d=s1.second;
  int f0 = ccw(a,b,c) * ccw(a,b,d);
  int f1 = ccw(c,d,a) * ccw(c,d,b);
  return (f0<=0 && f1<=0);
}
 
bool isCrossLS(L l,S s){
  P a=l.first, b=l.second;
  P c=s.first, d=s.second;
  return ( ccw(a,b,c) * ccw(a,b,d) <= 0 );
}
 
ldouble distLP(L l,P p){
  P a=l.first, b=l.second;
  ldouble res = cross(b-a,p-a) / abs(b-a);
  return abs(res);
}
 
ldouble distSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return distLP(s,p);
}
 
ldouble distSS(S s0,S s1){
  if( isCrossSS(s0,s1) )return 0;
  ldouble res0 = min( distSP( s0, s1.first ) , distSP(s0, s1.second) );
  ldouble res1 = min( distSP( s1, s0.first ) , distSP(s1, s0.second) );
  return min(res0,res1);
}
 
P getCrossLL(L l0,L l1){
  P a=l0.first, b=l0.second;
  P c=l1.first, d=l1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
 
  
int inPolygon(vecP &t,P p){
  int n=t.size();
  ldouble sum=0;
  for(int i=0;i<n;i++){
    P a=t[i],b=t[(i+1==n?0:i+1)];
    if( ccw(a,b,p)==0 )return 1;
    sum+= getArg(a-p,b-p);
  }
  if( abs(sum) < eps )return 0;
  else return 2;
}
 
vecP andrewScan(vecP &t){
  int N=t.size(),C=0;
  vecP R(N);
  for(int i=0;i<N;i++){
    while(2<=C&&ccw(R[C-2],R[C-1],t[i])==-1)C--;
    R[C++]=t[i];
  }
  vecP res(C);
  for(int i=0;i<C;i++)res[i]=R[i];
  return res;
}
  
vecP convexHull(vecP &t){
  sort(t.begin(),t.end());
  vecP u=andrewScan(t);
  reverse(t.begin(),t.end());
  vecP l=andrewScan(t);
  for(int i=1;i+1<(int)l.size();i++)u.push_back(l[i]);
  return u;
}
 
vecP cutConvex(vecP &t,L l){
  P a=l.first, b=l.second;
  int N=t.size();
  vecP res;
  for(int i=0;i<N;i++){
    P c=t[i],d=t[(i+1)%N];
    int C=ccw(a,b,c),D=ccw(a,b,d);
    if(C!=-1)res.push_back(c);
    if(C==-D&&abs(C)==1)res.push_back(getCrossLL( l ,L(c,d) ));
  }
  return res;
}
 
P getVector(const vecP &t, int id){
  int n=t.size();
  return t[ (id+1)%n ] - t[id%n];
}
 
ldouble convex_diameter(vecP &t) {
  int n = t.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(t[i]) > imag(t[is])) is = i;
    if (imag(t[i]) < imag(t[js])) js = i;
  }
  ldouble maxd = norm(t[is]-t[js]);
  
  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
     
    if (cross( getVector(t,i), getVector(t,j)) >= 0) j = (j+1) % n;
     
    else i = (i+1) % n;
    if (norm(t[i]-t[j]) > maxd) {
      maxd = norm(t[i]-t[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}
 
bool compare_y(const P &a,const P &b){
  return a.imag() < b.imag();
}
 
ldouble closest_pair(P *a, int n){
  if(n <= 1) return 1e30;
  int m = n / 2;
  ldouble x = a[m].real();
  ldouble d = min(closest_pair(a, m), closest_pair(a + m, n - m));
  inplace_merge(a, a + m, a + n, compare_y);
  vector<P> b;
  for(int i=0;i<n;i++){
    if( abs(a[i].real() - x) >= d) continue;
    for(int j=0;j<(int)b.size();j++){
      ldouble dx = real(a[i] - b[b.size() - j - 1]);
      ldouble dy = imag(a[i] - b[b.size() - j - 1]);
      if(dy >= d) break;
      d = min(d, sqrt(dx * dx + dy * dy));
    }
    b.push_back(a[i]);
  }
  return d;
}
 
P _pool[200005];
ldouble minDist(vecP &t){
  int n=t.size();
  for(int i=0;i<n;i++)_pool[i]=t[i];
  sort( _pool, _pool+n);
  return closest_pair(_pool, n);
}
 
int getStateCC(C a,C b){
  ldouble ar=a.second, br=b.second;
  ldouble dist=abs(a.first-b.first);
  if(dist>ar+br+eps)return 4;
  if(dist>ar+br-eps)return 3;
  if(dist>abs(ar-br)+eps)return 2;
  if(dist>abs(ar-br)-eps)return 1;
  return 0;
}
 
P getCrossCC(C a,C b){
  P p1=a.first, p2=b.first;
  ldouble r1=a.second, r2=b.second;
  ldouble cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA,Sqrt(1.0-cA*cA));
}
 
P getTangentCP_(C a,P p,int flg){
  P base=a.first-p;
  ldouble ar=a.second;
  ldouble w=Sqrt(norm(base)-ar*ar);
  P s=p+base*P(w,ar * flg)/norm(base)*w;
  return s;
}
 
vector<S> getTangentCP(C a,P p){
  vector<S> res;
  P s=getTangentCP_(a,p,1);
  P t=getTangentCP_(a,p,-1);
   
  if( eq(s,t) ){
    res.push_back( S(s, s+(a.first-p)*P(0,1) ) ); 
  }else{
    res.push_back( S(p,s) );
    res.push_back( S(p,t) );
  }
  return res;
}
 
S getInTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble w=ar+br;
  ldouble h=Sqrt(norm(base)-w*w);
  P k=base*P(w,h*flg)/norm(base);
  return S(ap+k*ar,bp-k*br);
}
   
S getOutTangent(C a,C b,ldouble flg=1.0){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  P base=bp-ap;
  ldouble h=br-ar;
   
  ldouble w=Sqrt(norm(base)-h*h);
  P k=base*P(w,h*flg)/norm(base)*P(0,flg);
  return S(ap+k*ar,bp+k*br);
}
   
vector<S> getTangentCC(C a,C b){
  P ap=a.first,bp=b.first;
  ldouble ar=a.second,br=b.second;
   
  vector<S> res;
  ldouble dist=abs(ap-bp);
     
  if(dist>ar+br+eps)
    res.push_back(getInTangent(a,b,1));
   
  if(dist>ar+br-eps)
    res.push_back(getInTangent(a,b,-1));
   
  if(dist>abs(ar-br)+eps)
    res.push_back(getOutTangent(a,b,1));
   
  if(dist>abs(ar-br)-eps)
    res.push_back(getOutTangent(a,b,-1));
   
  return res;
}
 
 
vecP getCrossCL(C cir,L l){
  P a=l.first, b=l.second;
  ldouble cr=cir.second;
  P cp=cir.first;
   
  vecP res;
  P base=b-a,  target=project(a,b,cp);
   
  ldouble length=abs(base), h=abs(cp-target);
  base/=length;
   
  if(cr+eps<h)return res;
  ldouble w=Sqrt(cr*cr-h*h);
  ldouble L=getTime( normal(b-a) ,target-a)-w,  R=L+w*2.0;
   
  res.push_back(a+base*L);
  if( eq(L,R) )return res;
  res.push_back(a+base*R);
 
  return res;
}
 
vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    //  if( ccw(s.first,s.second, tmp[i] ) == 0)
    if( onSP( s, tmp[i] ) )
      res.push_back(tmp[i]);
  return res;
}
 
ldouble getArea(C c,P a,P b){
  P cp=c.first;
  ldouble cr=c.second;
   
  P va=cp-a,  vb=cp-b;
  ldouble A=abs(va), B=abs(vb);
  ldouble f=cross(va,vb), d=distSP( S(a,b) ,cp), res=0;
   
  if( eq(0, f ) )return 0;
  if(A<cr+eps&&B<cr+eps)return f*0.5;
  if(d>cr-eps)return cr*cr*PI*getArg(va,vb)/PI2;
    
  vecP u=getCrossCS(c, S(a,b) );
   
  assert( !u.empty() );
  u.insert(u.begin(), a),  u.push_back(b);
  
  for(int i=0;i+1<(int)u.size();i++) res+=getArea(c,u[i],u[i+1]);
  return res;
}
  
ldouble getCrossArea(vecP t,C c){
  int n=t.size();
  if(n<3)return 0;
  ldouble res=0;
  for(int i=0;i<n;i++){
    P a=t[i], b=t[(i+1)%n];
    res+=getArea(c,a,b);
  }
  return res;
}
 
 
ldouble calcPolygonArea(const vecP &t){
  ldouble res=0;
  int n=t.size();
  for(int i=0;i<n;i++){
    res+= cross( t[ (i+1)%n ],t[i] );
  }
  return abs(res)*0.5;
}


bool check(const vector<S> &t,const vector<P> &u, ldouble r){
  vector<P> targets;
  for(int i=0;i<(int)t.size();i++){
    for(int j=0;j<(int)u.size();j++){
      vector<P> tmp = getCrossCS( C(u[j],r), t[i] );
      for(int k=0;k<(int)tmp.size();k++)targets.push_back(tmp[k]);
      targets.push_back(t[i].first);
      targets.push_back(t[i].second);
    }
  }
  sort( targets.begin(), targets.end() );
  targets.erase( unique(targets.begin(), targets.end() ), targets.end() );
  for(int i=0;i<(int)targets.size();i++){

    ldouble mini=1e9;
    for(int j=0;j<(int)u.size();j++){
      ldouble dist=abs(targets[i]-u[j]);
      mini=min(mini,dist);
    }
    if( mini > r - eps )return false;
  }
  return true;
}

ldouble solve(const vector<S> &t,const vector<P> &u){
  ldouble left=0, right=1e6, mid;
  for(int i=0;i<50;i++){
    mid=(left+right)*0.5;
    if( check(t,u,mid) )right=mid;
    else left=mid;
  }
  return left;
}

int main(){
  
  int n;
  scanf("%d",&n);
  P cp=P(0,0);
  vector< P > t(n);
  for(int i=0;i<n;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    t[i]=P(x,y);
    cp+=t[i];
  }
  
  t.push_back( cp / (ldouble)n );
  
  
  int m;
  scanf("%d",&m);
  vector< P > u(m);
  for(int i=0;i<m;i++){
    int x,y;
    scanf("%d %d",&x,&y);
    u[i]=P(x,y);
  }

  vector< S > w;
  for(int i=0;i<n;i++){
    for(int j=0;j<i;j++){
      w.push_back( S(t[i],t[j]) );
    }
  }
  
  printf("%.10f\n", (double)solve(w,u) );
  return 0;
  
}
accuracy: 0.16666666666666666
time_ms: 20
memory_kb: 9672
final_rank: 19

code_snippet: #include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<math.h>
#include<numeric>
#include<cassert>
#include<random>
#include<deque>
#include<chrono>
#include<unordered_map>
#include<list>
#include<fstream>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pi;
typedef pair<double,double> pd;
const ll E=1e18+7;
#define F first
#define S second
#define MK make_pair
const ll MOD=1000000007;

const double EPS=1e-7;
#define equals(a,b) (fabs(a-b)<EPS)

struct point{
  double x,y;
    
  point(double x=0,double y=0):x(x),y(y){}
    
  point operator + (const point &P) const {
    return point(x+P.x,y+P.y);
  }
    
  point operator - (const point &P) const {
    return point(x-P.x,y-P.y);
  }
    
  point operator * (const double &D) const {
    return point(x*D,y*D);
  }
    
  point operator / (const double &D) const {
    return point(x/D,y/D);
  }
    
  bool operator == (const point &P) const {
    if(fabs(x-P.x)<EPS && fabs(y-P.y)<EPS){return true;}
    if(fabs(x-P.x)/max(fabs(x),fabs(P.x))<EPS && fabs(y-P.y)/max(fabs(y),fabs(P.y))<EPS){return true;}
    return false;
  }
    
  bool operator != (const point &P) const {
    return !((*this)==P);
  }
    
  double norm() const {
    return x*x+y*y;
  }
    
  double abs() const {
    return sqrt(norm());
  }
    
  //ax=y
  double equation() const {
    return y/x;
  }
};

double dot(const point &a,const point &b){
  return a.x*b.x+a.y*b.y;
}

double cross(const point &a,const point &b){
  return a.x*b.y-a.y*b.x;
}

point mid_point(const point &a,const point &b){
  return point(a.x+b.x,a.y+b.y)/2;
}

struct line{
  point s,t;
    
  line(point s,point t):s(s),t(t){}
    
  bool operator == (const line &L) const {
    return s==L.s && t==L.t;
  }
    
  //ax+b=y
  pair<double,double> equation() const {
    double a=(t-s).equation();
    double b=t.y-t.x*a;
    return {a,b};
  }
};

//直行判定
bool isOrthogonal(const point &a,const point &b){
  return equals(dot(a,b),0.0);
}

bool isOrthogonal(const line &a,const line &b){
  return isOrthogonal(a.t-a.s,b.t-a.s);
}

//平行判定
bool isParallel(const point &a,const point &b){
  return equals(cross(a,b),0.0);
}

bool isParallel(const line &a,const line &b){
  return isParallel(a.t-a.s,b.t-b.s);
}

//射影
point project(const line &L,const point &P){
  point base=L.t-L.s;
  double r=dot(P-L.s,base)/base.norm();
  return L.s+base*r;
}

//点と点の距離
double getDistancePP(const point &a,const point &b){
  return (a-b).abs();
}

//直線と点の距離
double getDistanceLP(const line &L,const point &P){
  return fabs(cross(L.t-L.s,P-L.s)/(L.t-L.s).abs());
}

//線分と点の距離
double getDistanceSP(const line &L,const point &P){
  if(dot(L.t-L.s,P-L.s)<0.0){return (P-L.s).abs();}
  if(dot(L.s-L.t,P-L.t)<0.0){return (P-L.t).abs();}
  return getDistanceLP(L,P);
}


static const int COUNTER_CLOCKWISE=1;
static const int CLOCKWISE=-1;
static const int ONLINE_BACK=2;
static const int ONLINE_FRONT=-2;
static const int ON_SEGMENT=0;

int ccw(const point &p0,const point &p1,const point &p2){
  point a=p1-p0;
  point b=p2-p0;
  if(cross(a,b)>EPS){return COUNTER_CLOCKWISE;}
  if(cross(a,b)<-EPS){return CLOCKWISE;}
  if(dot(a,b)<-EPS){return ONLINE_BACK;}
  if(a.norm()<b.norm()){return ONLINE_FRONT;}
  return ON_SEGMENT;
}

bool intersect(const point &p1,const point &p2,const point &p3,const point &p4){
  return ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 && ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0;
}

//線分と線分の交差判定
bool intersect(const line &a,const line &b){
  return intersect(a.s,a.t,b.s,b.t);
}

//線分と線分の交点
point XpointSS(const line &a,const line &b){
  point base=b.t-b.s;
  double d1=fabs(cross(base,a.s-b.s));
  double d2=fabs(cross(base,a.t-b.s));
  double t=d1/(d1+d2);
  return a.s+(a.t-a.s)*t;
}



void show(const point &p){cout<<p.x<<" "<<p.y<<endl;}



typedef vector<point> polygon;

bool isInConvex(const polygon &poly,const point &P){
  int sign=ccw(poly[0],poly[1],P);
  for(int i=2;i<poly.size();i++){
    if(ccw(poly[i-1],poly[i],P)!=sign){return false;}
  }
  if(ccw(poly[poly.size()-1],poly[0],P)!=sign){return false;}
  return true;
}

//0::false 1::is_in //2::on_line
ll is_in_polygon(const polygon &P,const point &a){
  bool x=false;
  for(int i=1;i<=P.size();i++){
    point A=a-P[i-1];
    point B=a-P[i%P.size()];
    if(abs(cross(A,B))<EPS && dot(A,B)<EPS){return 0;}
    if(A.y>B.y){swap(A,B);}
    if(A.y<EPS && EPS<B.y && cross(A,B)>EPS){x=!x;}
  }
  return (x?1:0);
}

static const point err(1e18,1e18);

//直交ベクトル
point OrthogonalVector(const line &L){
  point a=L.t-L.s;
  return point(a.y,a.x*-1);
}

line mid_line(const point &a,const point &b){
  point s=mid_point(a,b);
  point t=s+OrthogonalVector(line(a,b));
  return line(s,t);
}

//線分が直線と交わるか
bool XSL(const line &a,const line &b){
  int A=ccw(b.s,b.t,a.s);
  int B=ccw(b.s,b.t,a.t);
  if(A==ONLINE_BACK || A==ONLINE_FRONT){return true;}
  if(B==ONLINE_BACK || B==ONLINE_FRONT){return true;}
  if(A*B<=0){return true;}
  return false;
}

//直線と直線の交点
point XpointLL(const line &a,const line &b){
  if(a.s==a.t || b.s==b.t){return err;}
  if(a.s==b.s || a.s==b.t){return a.s;}
  if(a.t==b.s || a.t==b.t){return a.t;}
  if(isParallel(a,b)){return err;}
  if(isOrthogonal(a,b)){return project(a,b.s);}
  if(intersect(a,b)){return XpointSS(a,b);}
  //ccw(a.s,a.t,b.s)*ccw(a.s,a.t,b.t)<=0
  if(XSL(b,a)){
    double d1=getDistancePP(project(a,b.s),b.s);
    double d2=getDistancePP(project(a,b.t),b.t);
    point base=b.t-b.s;
    return b.s+base*d1/(d2+d1);
  }
  //ccw(b.s,b.t,a.s)*ccw(b.s,b.t,a.t)<=0
  if(XSL(a,b)){
    double d1=getDistancePP(project(b,a.s),a.s);
    double d2=getDistancePP(project(b,a.t),a.t);
    point base=a.t-a.s;
    return a.s+base*d1/(d2+d1);
  }
  double d1=getDistancePP(project(a,b.s),b.s);
  double d2=getDistancePP(project(a,b.t),b.t);
  if(d1<d2){
    return b.s+(b.s-b.t)*(d1/(d2-d1));
  }
  return b.t+(b.t-b.s)*(d2/(d1-d2));
}

//間に合わせ
bool X(const line &a,const point &P){
  double mix=min(a.s.x,a.t.x);
  double mxx=max(a.s.x,a.t.x);
  double miy=min(a.s.y,a.t.y);
  double mxy=max(a.s.y,a.t.y);
  if(mxx>=P.x && P.x>=mix && mxy>=P.y && P.y>=miy){return true;}
  return false;
}

//線分と直線の交点
point XpointSL(const line &a,const line &b){
  point ret=XpointLL(b,a);
  /*
  if(ret!=XpointLL(a,b)){
    show(a.s);show(a.t);
    show(b.s);show(b.t);
    show(ret);show(XpointLL(a,b));
    assert(false);
  }
  */
  //assert(ret==XpointLL(a,b));
  if(ret==err){return err;}
  if(X(a,ret)){return ret;}
  //if(ccw(a.s,a.t,ret)==ON_SEGMENT){return ret;}
  return err;
}

//外心
point Circumcenter(const point &a,const point &b,const point &c){
  if(a==b || b==c || c==a){return err;}
  int w=ccw(a,b,c);
  if(w!=COUNTER_CLOCKWISE && w!=CLOCKWISE){return err;}
  line l1=mid_line(a,b);
  line l2=mid_line(a,c);
  return XpointLL(l1,l2);
}

double solve(polygon P,polygon C){
  polygon test=P;
  for(int i=0;i<C.size();i++){
    for(int t=i+1;t<C.size();t++){
      line L=mid_line(C[i],C[t]);
      for(int j=1;j<P.size();j++){
	point p=XpointSL(line(P[j-1],P[j]),L);
	if(p!=err){test.push_back(p);}
      }
      point p=XpointSL(line(P[P.size()-1],P[0]),L);
      if(p!=err){test.push_back(p);}
    }
  }
  for(int i=0;i<C.size();i++){
    for(int t=i+1;t<C.size();t++){
      for(int h=t+1;h<C.size();h++){
	point p=Circumcenter(C[i],C[t],C[h]);
	if(p==err){continue;}
	if(isInConvex(P,p)){test.push_back(p);}
      }
    }
  }
  double mx=0;
  for(int i=0;i<test.size();i++){
    double mi=E;
    for(int t=0;t<C.size();t++){
      mi=min(mi,getDistancePP(test[i],C[t]));
    }
    mx=max(mx,mi);
  }
  return mx;
}




int main(){
  cout<<fixed<<setprecision(12);
  ll n,m;
  cin>>n;
  polygon P,C;
  for(int i=0;i<n;i++){
    double a,b;
    cin>>a>>b;
    P.push_back(point(a,b));
  }
  cin>>m;
  for(int t=0;t<m;t++){
    double a,b;
    cin>>a>>b;
    C.push_back(point(a,b));
  }
  cout<<solve(P,C)+0.00001<<endl;
    
    
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6240
final_rank: 6

code_snippet: #include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<math.h>
#include<numeric>
#include<cassert>
#include<random>
#include<deque>
#include<chrono>
#include<unordered_map>
#include<list>
#include<fstream>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pi;
typedef pair<double,double> pd;
const ll E=1e18+7;
#define F first
#define S second
#define MK make_pair
const ll MOD=1000000007;

const double EPS=1e-7;
#define equals(a,b) (fabs(a-b)<EPS)

struct point{
  double x,y;
    
  point(double x=0,double y=0):x(x),y(y){}
    
  point operator + (const point &P) const {
    return point(x+P.x,y+P.y);
  }
    
  point operator - (const point &P) const {
    return point(x-P.x,y-P.y);
  }
    
  point operator * (const double &D) const {
    return point(x*D,y*D);
  }
    
  point operator / (const double &D) const {
    return point(x/D,y/D);
  }
    
  bool operator == (const point &P) const {
    if(fabs(x-P.x)<EPS && fabs(y-P.y)<EPS){return true;}
    if(fabs(x-P.x)/max(fabs(x),fabs(P.x))<EPS && fabs(y-P.y)/max(fabs(y),fabs(P.y))<EPS){return true;}
    return false;
  }
    
  bool operator != (const point &P) const {
    return !((*this)==P);
  }
    
  double norm() const {
    return x*x+y*y;
  }
    
  double abs() const {
    return sqrt(norm());
  }
    
  //ax=y
  double equation() const {
    return y/x;
  }
};

double dot(const point &a,const point &b){
  return a.x*b.x+a.y*b.y;
}

double cross(const point &a,const point &b){
  return a.x*b.y-a.y*b.x;
}

point mid_point(const point &a,const point &b){
  return point(a.x+b.x,a.y+b.y)/2;
}

struct line{
  point s,t;
    
  line(point s,point t):s(s),t(t){}
    
  bool operator == (const line &L) const {
    return s==L.s && t==L.t;
  }
    
  //ax+b=y
  pair<double,double> equation() const {
    double a=(t-s).equation();
    double b=t.y-t.x*a;
    return {a,b};
  }
};

//直行判定
bool isOrthogonal(const point &a,const point &b){
  return equals(dot(a,b),0.0);
}

bool isOrthogonal(const line &a,const line &b){
  return isOrthogonal(a.t-a.s,b.t-a.s);
}

//平行判定
bool isParallel(const point &a,const point &b){
  return equals(cross(a,b),0.0);
}

bool isParallel(const line &a,const line &b){
  return isParallel(a.t-a.s,b.t-b.s);
}

//射影
point project(const line &L,const point &P){
  point base=L.t-L.s;
  double r=dot(P-L.s,base)/base.norm();
  return L.s+base*r;
}

//点と点の距離
double getDistancePP(const point &a,const point &b){
  return (a-b).abs();
}

//直線と点の距離
double getDistanceLP(const line &L,const point &P){
  return fabs(cross(L.t-L.s,P-L.s)/(L.t-L.s).abs());
}

//線分と点の距離
double getDistanceSP(const line &L,const point &P){
  if(dot(L.t-L.s,P-L.s)<0.0){return (P-L.s).abs();}
  if(dot(L.s-L.t,P-L.t)<0.0){return (P-L.t).abs();}
  return getDistanceLP(L,P);
}


static const int COUNTER_CLOCKWISE=1;
static const int CLOCKWISE=-1;
static const int ONLINE_BACK=2;
static const int ONLINE_FRONT=-2;
static const int ON_SEGMENT=0;

int ccw(const point &p0,const point &p1,const point &p2){
  point a=p1-p0;
  point b=p2-p0;
  if(cross(a,b)>EPS){return COUNTER_CLOCKWISE;}
  if(cross(a,b)<-EPS){return CLOCKWISE;}
  if(dot(a,b)<-EPS){return ONLINE_BACK;}
  if(a.norm()<b.norm()){return ONLINE_FRONT;}
  return ON_SEGMENT;
}

bool intersect(const point &p1,const point &p2,const point &p3,const point &p4){
  return ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 && ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0;
}

//線分と線分の交差判定
bool intersect(const line &a,const line &b){
  return intersect(a.s,a.t,b.s,b.t);
}

//線分と線分の交点
point XpointSS(const line &a,const line &b){
  point base=b.t-b.s;
  double d1=fabs(cross(base,a.s-b.s));
  double d2=fabs(cross(base,a.t-b.s));
  double t=d1/(d1+d2);
  return a.s+(a.t-a.s)*t;
}



void show(const point &p){cout<<p.x<<" "<<p.y<<endl;}



typedef vector<point> polygon;

bool isInConvex(const polygon &poly,const point &P){
  int sign=ccw(poly[0],poly[1],P);
  for(int i=2;i<poly.size();i++){
    if(ccw(poly[i-1],poly[i],P)!=sign){return false;}
  }
  if(ccw(poly[poly.size()-1],poly[0],P)!=sign){return false;}
  return true;
}

//0::false 1::is_in //2::on_line
ll is_in_polygon(const polygon &P,const point &a){
  bool x=false;
  for(int i=1;i<=P.size();i++){
    point A=a-P[i-1];
    point B=a-P[i%P.size()];
    if(abs(cross(A,B))<EPS && dot(A,B)<EPS){return 0;}
    if(A.y>B.y){swap(A,B);}
    if(A.y<EPS && EPS<B.y && cross(A,B)>EPS){x=!x;}
  }
  return (x?1:0);
}

static const point err(1e18,1e18);

//直交ベクトル
point OrthogonalVector(const line &L){
  point a=L.t-L.s;
  return point(a.y,a.x*-1);
}

line mid_line(const point &a,const point &b){
  point s=mid_point(a,b);
  point t=s+OrthogonalVector(line(a,b));
  return line(s,t);
}

//線分が直線と交わるか
bool XSL(const line &a,const line &b){
  int A=ccw(b.s,b.t,a.s);
  int B=ccw(b.s,b.t,a.t);
  if(A==ONLINE_BACK || A==ONLINE_FRONT){return true;}
  if(B==ONLINE_BACK || B==ONLINE_FRONT){return true;}
  if(A*B<=0){return true;}
  return false;
}

//直線と直線の交点
point XpointLL(const line &a,const line &b){
  if(a.s==a.t || b.s==b.t){return err;}
  if(a.s==b.s || a.s==b.t){return a.s;}
  if(a.t==b.s || a.t==b.t){return a.t;}
  if(isParallel(a,b)){return err;}
  if(isOrthogonal(a,b)){return project(a,b.s);}
  if(intersect(a,b)){return XpointSS(a,b);}
  //ccw(a.s,a.t,b.s)*ccw(a.s,a.t,b.t)<=0
  if(XSL(b,a)){
    double d1=getDistancePP(project(a,b.s),b.s);
    double d2=getDistancePP(project(a,b.t),b.t);
    point base=b.t-b.s;
    return b.s+base*d1/(d2+d1);
  }
  //ccw(b.s,b.t,a.s)*ccw(b.s,b.t,a.t)<=0
  if(XSL(a,b)){
    double d1=getDistancePP(project(b,a.s),a.s);
    double d2=getDistancePP(project(b,a.t),a.t);
    point base=a.t-a.s;
    return a.s+base*d1/(d2+d1);
  }
  double d1=getDistancePP(project(a,b.s),b.s);
  double d2=getDistancePP(project(a,b.t),b.t);
  if(d1<d2){
    return b.s+(b.s-b.t)*(d1/(d2-d1));
  }
  return b.t+(b.t-b.s)*(d2/(d1-d2));
}

//間に合わせ
bool X(const line &a,const point &P){
  double mix=min(a.s.x,a.t.x);
  double mxx=max(a.s.x,a.t.x);
  double miy=min(a.s.y,a.t.y);
  double mxy=max(a.s.y,a.t.y);
  if(mxx>=P.x && P.x>=mix && mxy>=P.y && P.y>=miy){return true;}
  return false;
}

//線分と直線の交点
point XpointSL(const line &a,const line &b){
  point ret=XpointLL(b,a);
  /*
  if(ret!=XpointLL(a,b)){
    show(a.s);show(a.t);
    show(b.s);show(b.t);
    show(ret);show(XpointLL(a,b));
    assert(false);
  }
  */
  //assert(ret==XpointLL(a,b));
  if(ret==err){return err;}
  if(X(a,ret)){return ret;}
  //if(ccw(a.s,a.t,ret)==ON_SEGMENT){return ret;}
  return err;
}

//外心
point Circumcenter(const point &a,const point &b,const point &c){
  if(a==b || b==c || c==a){return err;}
  int w=ccw(a,b,c);
  if(w!=COUNTER_CLOCKWISE && w!=CLOCKWISE){return err;}
  line l1=mid_line(a,b);
  line l2=mid_line(a,c);
  return XpointLL(l1,l2);
}

double solve(polygon P,polygon C){
  polygon test=P;
  for(int i=0;i<C.size();i++){
    for(int t=i+1;t<C.size();t++){
      line L=mid_line(C[i],C[t]);
      for(int j=1;j<P.size();j++){
	point p=XpointSL(line(P[j-1],P[j]),L);
	if(p!=err){test.push_back(p);}
      }
      point p=XpointSL(line(P[P.size()-1],P[0]),L);
      if(p!=err){test.push_back(p);}
    }
  }
  for(int i=0;i<C.size();i++){
    for(int t=i+1;t<C.size();t++){
      for(int h=t+1;h<C.size();h++){
	point p=Circumcenter(C[i],C[t],C[h]);
	if(p==err){continue;}
	if(isInConvex(P,p)){test.push_back(p);}
      }
    }
  }
  double mx=0;
  for(int i=0;i<test.size();i++){
    double mi=E;
    for(int t=0;t<C.size();t++){
      mi=min(mi,getDistancePP(test[i],C[t]));
    }
    mx=max(mx,mi);
  }
  return mx;
}




int main(){
  //cout<<fixed<<setprecision(12);
  ll n,m;
  cin>>n;
  polygon P,C;
  for(int i=0;i<n;i++){
    double a,b;
    cin>>a>>b;
    P.push_back(point(a,b));
  }
  cin>>m;
  for(int t=0;t<m;t++){
    double a,b;
    cin>>a>>b;
    C.push_back(point(a,b));
  }
  cout<<solve(P,C)<<endl;
    
    
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6356
final_rank: 7