Problem:
Convex-Cut

N個の頂点からなる凸多角形が与えられる。各頂点の座標は反時計周りに(X1, Y1), (X2 ,Y2), ……, (XN, YN)で表わされる。
点Pを通るどのような直線で凸多角形を切断しても、切断後に得られる2つの凸多角形の面積が等しいような点Pの座標を求めよ。

Input

入力は以下の形式で与えられる。

N
X1 Y1
X2 Y2
……
XN YN

Constraints

入力は全て整数である

3 ≤ N ≤ 50

0 ≤ |Xi|, |Yi| ≤ 1000000

入力の多角形は単純な凸多角形である。

出力は、出力座標を(X, Y)、厳密解を(cX, cY)とした時にmax(|X-cX|, |Y-cY|) ≤ 0.0001を満たす必要がある

Output

問題文の条件を満たす点があるのならば、その点の座標を

X Y

の形式で出力せよ。
点が存在しない場合は"NA"と1行に出力せよ。

Sample Input 1

4
100 100
0 100
0 0
100 0

以下の図に対応する。

Output for the Sample Input 1

50.00000 50.00000

Sample Input 2

3
100 100
0 100
0 0

Output for the Sample Input 2

NA

以下の図に対応する。

Solution in C++11 (judge verdict: Accepted)

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

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
//template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<58;
const long double eps=1e-6;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
    os << "[";
    for (const auto &v : vec) {
    	os << v << ",";
    }
    os << "]";
    return os;
}

typedef complex<long double> point;
typedef pair<point,point> line;
bool equal(const long double x1,const long double x2){ return abs(x1-x2)<eps; }
bool equal(const point& a,const point& b){ return equal(a.real(),b.real()) and equal(a.imag(),b.imag()); }
long double length(const point& a){ return abs(a); }
long double distance(const point& a,const point& b){ return abs(a-b); }
long double dot(const point& a,const point& b){ return a.real()*b.real()+a.imag()*b.imag(); }
long double cross(const point& a,const point& b){ return a.real()*b.imag()-a.imag()*b.real(); }
bool is_orthogonal(const point& a1,const point& a2,const point& b1,const point& b2){ return equal(dot(a1-a2,b1-b2),0.0); }
bool is_orthogonal(const line& l,const line& m){ return is_orthogonal(l.first,l.second,m.first,m.second); }
bool is_parallel(const point& a1,const point& a2,const point& b1,const point& b2){ return equal(cross(a1-a2, b1-b2),0.0); }
bool is_parallel(const line& l,const line& m){ return is_parallel(l.first,l.second,m.first,m.second); }
int ccw(point a,point b,point 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;
}
bool intersectLL(const line& l, const line& m){
    return abs(cross(l.second-l.first, m.second-m.first)) > eps || // non-parallel
           abs(cross(l.second-l.first, m.first-l.first)) < eps;   // same line
}
bool intersectLS(const line& l, const line& s){
    return cross(l.second-l.first, s.first-l.first)*       // s.first is left of l
           cross(l.second-l.first, s.second-l.first) < eps; // s.second is right of l
}
bool intersectLP(const line& l, const point& p){
    return abs(cross(l.second-p, l.first-p)) < eps;
}
bool intersectSS(const line& s, const line& t){
    return ccw(s.first,s.second,t.first)*ccw(s.first,s.second,t.second) <= 0 &&
           ccw(t.first,t.second,s.first)*ccw(t.first,t.second,s.second) <= 0;
}
bool intersectSP(const line& s, const point& p){
    return abs(s.first-p)+abs(s.second-p)-abs(s.second-s.first) < eps; // triangle inequality
}
point projection(const line& l, const point& p) {
    long double t = dot(p-l.first, l.first-l.second) / norm(l.first-l.second);
    return l.first + t*(l.first-l.second);
}
point reflection(const line& l, const point& p){
    return p+point((projection(l, p) - p).real()*2,(projection(l, p) - p).imag()*2);
}
long double distanceLP(const line &l, const point& p){
    return abs(p - projection(l, p));
}
long double distanceLL(const line &l, const line &m){
    return intersectLL(l, m) ? 0 : distanceLP(l, m.first);
}
long double distanceLS(const line &l, const line &s){
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s.first), distanceLP(l, s.second));
}
long double distanceSP(const line &s, const point& p) {
    const point r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s.first - p), abs(s.second - p));
}
long double distanceSS(const line &s, const line &t) {
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t.first), distanceSP(s, t.second)),
             min(distanceSP(t, s.second), distanceSP(t, s.second)));
}
// a1,a2???????????´?????¨b1,b2???????????´?????????????¨????
point intersection_l(const point& a1,const point& a2,const point& b1,const point& b2) {
  const point& a=a2-a1,b=b2-b1;
  return a1+a*cross(b, b1-a1)/cross(b, a);
}
point intersection_l(const line& l,const line& m){
    return intersection_l(l.first,l.second,m.first,m.second);
}
// ????§???¢????¬?????????¢???
long double area(const vector<point>& pol){
    long double s=0;
    rep(i,0,pol.size()) s+=cross(pol[i],pol[(i+1)%pol.size()]);
    return s/2;
}

vector<point> convex_cut(const vector<point>& ps, const line& l) {
    vector<point> res;
    for (int i = 0; i < ps.size(); ++i) {
        point a = ps[i], b = ps[(i+1)%ps.size()];
        if (ccw(l.first, l.second, a) != -1) res.push_back(a);
        if (ccw(l.first, l.second, a)*ccw(l.first, l.second, b) < 0) res.push_back(intersection_l(line(a, b), l));
    }
    return res;
}

void solve(){
    int n;
    cin >> n;
    vector<point> ps(n);
    for(point& p:ps){
        long double x,y;
        cin >> x >> y;
        p=point(x,y);
    }

    const long double s=area(ps);
    auto opt=[&](){
        long double left=inf,right=-inf;
        for(const auto& p:ps){
            if(p.real()<left) left=p.real();
            if(p.real()>right) right=p.real();
        }
        line l(point(left,0),point(left,1));
        long double lb=0,ub=distanceLP(l,point(right,0));
        rep(i,0,200){
            long double mid=(lb+ub)/2;
            l=line(point(left+mid,0),point(left+mid,1));
            if(area(convex_cut(ps,l))<=s/2) lb=mid;
            else ub=mid;
        }
        return l;
    };

    line l1=opt();
    for(auto& p:ps) p*=point(0,1);
    line l2=opt();
    l2=line(l2.first*point(0,-1),l2.second*point(0,-1));
    for(auto& p:ps) p*=point(0,-1);
    point ans=intersection_l(l1,l2);
    bool ok=true;
    const long double pi=3.14159265;
    rep(i,0,10000){
        const point tmp=ans+point(1,0)*point(cos(2*pi*i/10000),sin(2*pi*i/10000));
        if(abs(area(convex_cut(ps,line(ans,tmp)))-s/2)>eps){
            ok=false;
            break;
        }
    }
    if(ok) cout << ans.real() << " " << ans.imag() << endl;
    else cout << "NA" << endl;
}

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout << fixed << setprecision(8) << endl;
    solve();
    return 0;
}