Problem:
Convex-Cut
N個の頂点からなる凸多角形が与えられる。各頂点の座標は反時計周りに(X
1
, Y
1
), (X
2
,Y
2
), ……, (X
N
, Y
N
)で表わされる。
点Pを通るどのような直線で凸多角形を切断しても、切断後に得られる2つの凸多角形の面積が等しいような点Pの座標を求めよ。
Input
入力は以下の形式で与えられる。
N
X
1
Y
1
X
2
Y
2
……
X
N
Y
N
Constraints
入力は全て整数である
3 ≤ N ≤ 50
0 ≤ |X
i
|, |Y
i
| ≤ 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
以下の図に対応する。

Submitted solutions:

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000300

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
	vector_2d<T> get_cross_point(line<T> L2){
		line<T> L1(V1,V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
};

template <typename T>
struct triangle{
	vector_2d<T> V[3];
	
	triangle(vector_2d<T> V1,vector_2d<T> V2,vector_2d<T> V3){
		V[0] = V1;
		V[1] = V2;
		V[2] = V3;
	}
	
	vector_2d<T> get_circumcenter(){
		line<T> L1(V[0],V[1]);
		vector_2d<T> M1 = V[0].get_midpoint(V[1]);
		L1 = line<T>(M1,L1.b,L1.a);

		line<T> L2(V[1],V[2]);
		vector_2d<T> M2 = V[1].get_midpoint(V[2]);
		L2 = line<T>(M2,L2.b,L2.a);
				
		return L1.get_cross_point(L2);
	}
	
	T get_signed_area(){
		return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	bool is_inside(vector_2d<T> P){
		T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
		return abs(S - get_area())<eps;
	}
	
	bool is_clockwise(){
		vector_2d<T> X = V[1]-V[0],Y = V[2]-V[1];
		return X.x*Y.y-X.y*Y.x < 0.0;
	}
	
};

template <typename T>
struct polygon{
	vector<vector_2d<T>> V;
	polygon(vector<vector_2d<T>> v){
		V = v;
	}
	
	bool is_convex(){
		bool f = false;
		for(int i=0;i<V.size();i++){
			triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
			if(i==0)f = tri.is_clockwise();
			else{
				if(tri.is_clockwise()!=f)return false;
			}
		}
		return true;
	}
	
	T get_signed_area(){
		T ret = 0.0;
		for(int i=1;i<V.size()-1;i++){
			triangle<T> tri(V[0],V[i],V[i+1]);
			ret += tri.get_signed_area();
		}
		return ret;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	T get_diameter(){
		vector<T> dis(V.size());
		int now = 0;
		for(int i=0;i<V.size();i++){
			while(true){
				int next = (now+1)%V.size();
				if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
					now = next;
					continue;
				}
				else{
					break;
				}
			}
			dis[i] = V[i].get_dis(V[now]);
		}
		
		T ret = 0.0;
		for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
		
		return ret;
	}
	
	vector<vector_2d<T>> get_cross_point(line<T> L){
		vector<vector_2d<T>> ret;
		rep(i,V.size()){
			segment<T> S(V[i],V[(i+1)%V.size()]);
			vector_2d<T> p = S.get_cross_point(L);
			if(p.x<1e20)ret.push_back(p);
		}
		return ret;
	}		
	
	bool is_on_side(vector_2d<T> P){
		for(int i=0;i<V.size();i++){
			segment<T> l(V[i],V[(i+1)%V.size()]);
			if(l.get_dis(P)<eps)return true;
		}
		return false;
	}
	
	bool is_inside(vector_2d<T> P){
		if(is_on_side(P))return true;
		double R = 0.0;
		for(int i=0;i<V.size();i++){
			vector_2d<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
			R += p1.angle_difference(p2);
		}
		return abs(R)>=eps;
	}
};

int main(){	

	int N;
	cin>>N;
	
	vector_2d<double> G;
	
	vector<vector_2d<double>> V(N);
	rep(i,N){
		double x,y;
		cin>>x>>y;
		V[i] = vector_2d(x,y);
		G.update_x(1.0,V[i].x/N);
		G.update_y(1.0,V[i].y/N);
	}
	
	polygon<double> P(V);

	rep(i,10000){
		vector_2d<double> t(10000.0,0.0);
		t.update_dir(acos(-1.0)*i/10000.0);
		line L(G,G + t);
		
		vector<vector_2d<double>> X = P.get_cross_point(L);
		if(X.size()>=2){
			rep(j,X.size()-1){
				if(abs(X[j].get_dis(G)-X[j+1].get_dis(G))>eps){
					cout<<"NA"<<endl;
					return 0;
				}
			}
		}
	}
	
	cout<<fixed<<setprecision(10)<<G.x<<' '<<G.y<<endl;
	
	
    return 0;
}
accuracy: 0.48214285714285715
time_ms: 10
memory_kb: 3968
final_rank: 12

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000300

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
	vector_2d<T> get_cross_point(line<T> L2){
		line<T> L1(V1,V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
};

template <typename T>
struct triangle{
	vector_2d<T> V[3];
	
	triangle(vector_2d<T> V1,vector_2d<T> V2,vector_2d<T> V3){
		V[0] = V1;
		V[1] = V2;
		V[2] = V3;
	}
	
	vector_2d<T> get_circumcenter(){
		line<T> L1(V[0],V[1]);
		vector_2d<T> M1 = V[0].get_midpoint(V[1]);
		L1 = line<T>(M1,L1.b,L1.a);

		line<T> L2(V[1],V[2]);
		vector_2d<T> M2 = V[1].get_midpoint(V[2]);
		L2 = line<T>(M2,L2.b,L2.a);
				
		return L1.get_cross_point(L2);
	}
	
	T get_signed_area(){
		return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	bool is_inside(vector_2d<T> P){
		T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
		return abs(S - get_area())<eps;
	}
	
	bool is_clockwise(){
		vector_2d<T> X = V[1]-V[0],Y = V[2]-V[1];
		return X.x*Y.y-X.y*Y.x < 0.0;
	}
	
};

template <typename T>
struct polygon{
	vector<vector_2d<T>> V;
	polygon(vector<vector_2d<T>> v){
		V = v;
	}
	
	bool is_convex(){
		bool f = false;
		for(int i=0;i<V.size();i++){
			triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
			if(i==0)f = tri.is_clockwise();
			else{
				if(tri.is_clockwise()!=f)return false;
			}
		}
		return true;
	}
	
	T get_signed_area(){
		T ret = 0.0;
		for(int i=1;i<V.size()-1;i++){
			triangle<T> tri(V[0],V[i],V[i+1]);
			ret += tri.get_signed_area();
		}
		return ret;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	T get_diameter(){
		vector<T> dis(V.size());
		int now = 0;
		for(int i=0;i<V.size();i++){
			while(true){
				int next = (now+1)%V.size();
				if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
					now = next;
					continue;
				}
				else{
					break;
				}
			}
			dis[i] = V[i].get_dis(V[now]);
		}
		
		T ret = 0.0;
		for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
		
		return ret;
	}
	
	vector<vector_2d<T>> get_cross_point(line<T> L){
		vector<vector_2d<T>> ret;
		rep(i,V.size()){
			segment<T> S(V[i],V[(i+1)%V.size()]);
			vector_2d<T> p = S.get_cross_point(L);
			if(p.x<1e20)ret.push_back(p);
		}
		return ret;
	}		
	
	bool is_on_side(vector_2d<T> P){
		for(int i=0;i<V.size();i++){
			segment<T> l(V[i],V[(i+1)%V.size()]);
			if(l.get_dis(P)<eps)return true;
		}
		return false;
	}
	
	bool is_inside(vector_2d<T> P){
		if(is_on_side(P))return true;
		double R = 0.0;
		for(int i=0;i<V.size();i++){
			vector_2d<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
			R += p1.angle_difference(p2);
		}
		return abs(R)>=eps;
	}
};

int main(){	

	int N;
	cin>>N;
	
	vector_2d<double> G;
	
	vector<vector_2d<double>> V(N);
	rep(i,N){
		double x,y;
		cin>>x>>y;
		V[i] = vector_2d(x,y);
		G.update_x(1.0,V[i].x/N);
		G.update_y(1.0,V[i].y/N);
	}
	
	polygon<double> P(V);

	rep(i,10000){
		vector_2d<double> t(10000.0,0.0);
		t.update_dir(acos(-1.0)*i/10000.0);
		line L(G,G + t);
		
		vector<vector_2d<double>> X = P.get_cross_point(L);

		rep(j,X.size()-1){
			if(abs(X[j].get_dis(G)-X[j+1].get_dis(G))>eps){
				cout<<"NA"<<endl;
				return 0;
			}
		}
	}
	
	cout<<fixed<<setprecision(10)<<G.x<<' '<<G.y<<endl;
	
	
    return 0;
}
accuracy: 0.21428571428571427
time_ms: 10
memory_kb: 3968
final_rank: 15

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000300

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
	vector_2d<T> get_cross_point(line<T> L2){
		line<T> L1(V1,V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
};

template <typename T>
struct triangle{
	vector_2d<T> V[3];
	
	triangle(vector_2d<T> V1,vector_2d<T> V2,vector_2d<T> V3){
		V[0] = V1;
		V[1] = V2;
		V[2] = V3;
	}
	
	vector_2d<T> get_circumcenter(){
		line<T> L1(V[0],V[1]);
		vector_2d<T> M1 = V[0].get_midpoint(V[1]);
		L1 = line<T>(M1,L1.b,L1.a);

		line<T> L2(V[1],V[2]);
		vector_2d<T> M2 = V[1].get_midpoint(V[2]);
		L2 = line<T>(M2,L2.b,L2.a);
				
		return L1.get_cross_point(L2);
	}
	
	T get_signed_area(){
		return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	bool is_inside(vector_2d<T> P){
		T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
		return abs(S - get_area())<eps;
	}
	
	bool is_clockwise(){
		vector_2d<T> X = V[1]-V[0],Y = V[2]-V[1];
		return X.x*Y.y-X.y*Y.x < 0.0;
	}
	
};

template <typename T>
struct polygon{
	vector<vector_2d<T>> V;
	polygon(vector<vector_2d<T>> v){
		V = v;
	}
	
	bool is_convex(){
		bool f = false;
		for(int i=0;i<V.size();i++){
			triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
			if(i==0)f = tri.is_clockwise();
			else{
				if(tri.is_clockwise()!=f)return false;
			}
		}
		return true;
	}
	
	T get_signed_area(){
		T ret = 0.0;
		for(int i=1;i<V.size()-1;i++){
			triangle<T> tri(V[0],V[i],V[i+1]);
			ret += tri.get_signed_area();
		}
		return ret;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	T get_diameter(){
		vector<T> dis(V.size());
		int now = 0;
		for(int i=0;i<V.size();i++){
			while(true){
				int next = (now+1)%V.size();
				if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
					now = next;
					continue;
				}
				else{
					break;
				}
			}
			dis[i] = V[i].get_dis(V[now]);
		}
		
		T ret = 0.0;
		for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
		
		return ret;
	}
	
	vector<vector_2d<T>> get_cross_point(line<T> L){
		vector<vector_2d<T>> ret;
		rep(i,V.size()){
			segment<T> S(V[i],V[(i+1)%V.size()]);
			vector_2d<T> p = S.get_cross_point(L);
			if(p.x<1e20)ret.push_back(p);
		}
		return ret;
	}		
	
	bool is_on_side(vector_2d<T> P){
		for(int i=0;i<V.size();i++){
			segment<T> l(V[i],V[(i+1)%V.size()]);
			if(l.get_dis(P)<eps)return true;
		}
		return false;
	}
	
	bool is_inside(vector_2d<T> P){
		if(is_on_side(P))return true;
		double R = 0.0;
		for(int i=0;i<V.size();i++){
			vector_2d<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
			R += p1.angle_difference(p2);
		}
		return abs(R)>=eps;
	}
};

int main(){	

	int N;
	cin>>N;
	
	vector_2d<double> G;
	
	vector<vector_2d<double>> V(N);
	rep(i,N){
		double x,y;
		cin>>x>>y;
		V[i] = vector_2d(x,y);
		G.update_x(1.0,V[i].x/N);
		G.update_y(1.0,V[i].y/N);
	}
	
	polygon<double> P(V);

	rep(i,10000){
		vector_2d<double> t(100.0,0.0);
		t.update_dir(acos(-1.0)*i/10000.0);
		line L(G,G + t);
		
		vector<vector_2d<double>> X = P.get_cross_point(L);

		rep(j,X.size()-1){
			if(abs(X[j].get_dis(G)-X[j+1].get_dis(G))>eps){
				cout<<"NA"<<endl;
				return 0;
			}
		}
	}
	
	cout<<fixed<<setprecision(10)<<G.x<<' '<<G.y<<endl;
	
	
    return 0;
}
accuracy: 0.26785714285714285
time_ms: 10
memory_kb: 3988
final_rank: 14

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000300

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
	vector_2d<T> get_cross_point(line<T> L2){
		line<T> L1(V1,V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
};

template <typename T>
struct triangle{
	vector_2d<T> V[3];
	
	triangle(vector_2d<T> V1,vector_2d<T> V2,vector_2d<T> V3){
		V[0] = V1;
		V[1] = V2;
		V[2] = V3;
	}
	
	vector_2d<T> get_circumcenter(){
		line<T> L1(V[0],V[1]);
		vector_2d<T> M1 = V[0].get_midpoint(V[1]);
		L1 = line<T>(M1,L1.b,L1.a);

		line<T> L2(V[1],V[2]);
		vector_2d<T> M2 = V[1].get_midpoint(V[2]);
		L2 = line<T>(M2,L2.b,L2.a);
				
		return L1.get_cross_point(L2);
	}
	
	T get_signed_area(){
		return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	bool is_inside(vector_2d<T> P){
		T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
		return abs(S - get_area())<eps;
	}
	
	bool is_clockwise(){
		vector_2d<T> X = V[1]-V[0],Y = V[2]-V[1];
		return X.x*Y.y-X.y*Y.x < 0.0;
	}
	
};

template <typename T>
struct polygon{
	vector<vector_2d<T>> V;
	polygon(vector<vector_2d<T>> v){
		V = v;
	}
	
	bool is_convex(){
		bool f = false;
		for(int i=0;i<V.size();i++){
			triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
			if(i==0)f = tri.is_clockwise();
			else{
				if(tri.is_clockwise()!=f)return false;
			}
		}
		return true;
	}
	
	T get_signed_area(){
		T ret = 0.0;
		for(int i=1;i<V.size()-1;i++){
			triangle<T> tri(V[0],V[i],V[i+1]);
			ret += tri.get_signed_area();
		}
		return ret;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	T get_diameter(){
		vector<T> dis(V.size());
		int now = 0;
		for(int i=0;i<V.size();i++){
			while(true){
				int next = (now+1)%V.size();
				if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
					now = next;
					continue;
				}
				else{
					break;
				}
			}
			dis[i] = V[i].get_dis(V[now]);
		}
		
		T ret = 0.0;
		for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
		
		return ret;
	}
	
	vector<vector_2d<T>> get_cross_point(line<T> L){
		vector<vector_2d<T>> ret;
		rep(i,V.size()){
			segment<T> S(V[i],V[(i+1)%V.size()]);
			vector_2d<T> p = S.get_cross_point(L);
			if(p.x<1e20)ret.push_back(p);
		}
		return ret;
	}		
	
	bool is_on_side(vector_2d<T> P){
		for(int i=0;i<V.size();i++){
			segment<T> l(V[i],V[(i+1)%V.size()]);
			if(l.get_dis(P)<eps)return true;
		}
		return false;
	}
	
	bool is_inside(vector_2d<T> P){
		if(is_on_side(P))return true;
		double R = 0.0;
		for(int i=0;i<V.size();i++){
			vector_2d<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
			R += p1.angle_difference(p2);
		}
		return abs(R)>=eps;
	}
};

int main(){	

	int N;
	cin>>N;
	
	vector_2d<double> G;
	
	vector<vector_2d<double>> V(N);
	rep(i,N){
		double x,y;
		cin>>x>>y;
		V[i] = vector_2d(x,y);
		G.update_x(1.0,V[i].x/N);
		G.update_y(1.0,V[i].y/N);
	}
	
	polygon<double> P(V);
	
	rep(i,10000){
		vector_2d<double> t(1.0,0.0);
		t.update_dir(acos(-1.0)*i/10000.0);
		line L(G,G + t);
		
		vector<vector_2d<double>> X = P.get_cross_point(L);
		rep(j,X.size()-1){
			if(abs(X[j].get_dis(G)-X[j+1].get_dis(G))>eps){
				cout<<"NA"<<endl;
				return 0;
			}
		}
	}
	
	cout<<fixed<<setprecision(10)<<G.x<<' '<<G.y<<endl;
	
	
    return 0;
}
accuracy: 0.03571428571428571
time_ms: 10
memory_kb: 3992
final_rank: 16

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000300

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
	
	vector_2d<T> get_cross_point(line<T> L2){
		line<T> L1(V1,V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
};

template <typename T>
struct triangle{
	vector_2d<T> V[3];
	
	triangle(vector_2d<T> V1,vector_2d<T> V2,vector_2d<T> V3){
		V[0] = V1;
		V[1] = V2;
		V[2] = V3;
	}
	
	vector_2d<T> get_circumcenter(){
		line<T> L1(V[0],V[1]);
		vector_2d<T> M1 = V[0].get_midpoint(V[1]);
		L1 = line<T>(M1,L1.b,L1.a);

		line<T> L2(V[1],V[2]);
		vector_2d<T> M2 = V[1].get_midpoint(V[2]);
		L2 = line<T>(M2,L2.b,L2.a);
				
		return L1.get_cross_point(L2);
	}
	
	T get_signed_area(){
		return ((V[1].x-V[0].x)*(V[2].y-V[0].y) - (V[2].x-V[0].x)*(V[1].y-V[0].y))/2.0;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	bool is_inside(vector_2d<T> P){
		T S = triangle<T>(V[0],V[1],P).get_area() + triangle<T>(V[1],V[2],P).get_area() + triangle<T>(V[2],V[0],P).get_area();
		return abs(S - get_area())<eps;
	}
	
	bool is_clockwise(){
		vector_2d<T> X = V[1]-V[0],Y = V[2]-V[1];
		return X.x*Y.y-X.y*Y.x < 0.0;
	}
	
};

template <typename T>
struct polygon{
	vector<vector_2d<T>> V;
	polygon(vector<vector_2d<T>> v){
		V = v;
	}
	
	bool is_convex(){
		bool f = false;
		for(int i=0;i<V.size();i++){
			triangle<T> tri(V[i],V[(i+1)%V.size()],V[(i+2)%V.size()]);
			if(i==0)f = tri.is_clockwise();
			else{
				if(tri.is_clockwise()!=f)return false;
			}
		}
		return true;
	}
	
	T get_signed_area(){
		T ret = 0.0;
		for(int i=1;i<V.size()-1;i++){
			triangle<T> tri(V[0],V[i],V[i+1]);
			ret += tri.get_signed_area();
		}
		return ret;
	}
	
	T get_area(){
		return abs(get_signed_area());
	}
	
	T get_diameter(){
		vector<T> dis(V.size());
		int now = 0;
		for(int i=0;i<V.size();i++){
			while(true){
				int next = (now+1)%V.size();
				if(V[i].get_dis(V[now])<V[i].get_dis(V[next])+eps){
					now = next;
					continue;
				}
				else{
					break;
				}
			}
			dis[i] = V[i].get_dis(V[now]);
		}
		
		T ret = 0.0;
		for(int i=0;i<V.size();i++)ret = max(ret,dis[i]);
		
		return ret;
	}
	
	bool is_on_side(vector_2d<T> P){
		for(int i=0;i<V.size();i++){
			segment<T> l(V[i],V[(i+1)%V.size()]);
			if(l.get_dis(P)<eps)return true;
		}
		return false;
	}
	
	bool is_inside(vector_2d<T> P){
		if(is_on_side(P))return true;
		double R = 0.0;
		for(int i=0;i<V.size();i++){
			vector_2d<T> p1(V[i]-P),p2(V[(i+1)%V.size()]-P);
			R += p1.angle_difference(p2);
		}
		return abs(R)>=eps;
	}
	
	
	vector<vector_2d<T>> get_cross_point(line<T> L){
		vector<vector_2d<T>> ret;
		rep(i,V.size()){
			segment<T> S(V[i],V[(i+1)%V.size()]);
			vector_2d<T> t = S.get_cross_point(L);
			if(t.x<1e20){
				ret.push_back(t);
			}
		}
		return ret;
	}
};

int main(){	

	int n;
	cin>>n;
	vector_2d<double> G;
	vector<vector_2d<double>> V(n);
	rep(i,n){
		double x,y;
		cin>>x>>y;
		V[i] = vector_2d(x,y);
		G += V[i];
	}
	
	G.update_rad(1.0/n,0.0);
	polygon P(V);
	rep(i,100000){
		line L(G,G + vector_2d<double>(cos(acos(-1.0)/100000.0 * i),sin(acos(-1.0)/100000.0 * i)));
		vector<vector_2d<double>> X = P.get_cross_point(L);
		rep(i,X.size()){
			if(i==0)continue;
			if(abs(X[i].get_dis(G)-X[i-1].get_dis(G))>=eps){
				cout<<"NA"<<endl;
				return 0;
			}
		}
	}
	
	cout<<fixed<<setprecision(10)<<G.x<<' '<<G.y<<endl;
		
	
    return 0;
}
accuracy: 0.48214285714285715
time_ms: 150
memory_kb: 3968
final_rank: 13

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt"


#include <complex>

typedef long double ld;
typedef complex<ld> Point;
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()


const ld pi = acos(-1.0);
const ld dtop = pi / 180.;
const ld ptod = 1. / dtop;

namespace std {
  bool operator<(const Point &lhs, const Point &rhs) {
    if (lhs.real() < rhs.real() - eps) return true;
    if (lhs.real() > rhs.real() + eps) return false;
    return lhs.imag() < rhs.imag();
  }
}

Point input_point() {
  ld x, y;
  cin >> x >> y;
  return Point(x, y);
}

bool eq(const ld a, const ld b) {
  return (abs(a - b) < eps);
}

ld dot(const Point& a, const Point& b) {
  return real(conj(a) * b);
}

ld cross(const Point& a, const Point& b) {
  return imag(conj(a) * b);
}

class Line {
public:
  Point a, b;
  Line() : a(Point(0, 0)), b(Point(0, 0)) {}
  Line(Point a, Point b) : a(a), b(b) {}
  Point operator[](const int _num)const {
    if (_num == 0)return a;
    else if (_num == 1)return b;
    else {
      assert(false);
      return Point();
    }
  }
};

class Circle {
public:
  Point p;
  ld r;
  Circle() : p(Point(0, 0)), r(0) {}
  Circle(Point p, ld r) : p(p), r(r) {}
};

// CCW
int ccw(const Point& a, const Point &b, const Point &c) {
  const Point nb(b - a);
  const Point nc(c - a);
  if (cross(nb, nc) > eps) return 1;   // a,b,c
  if (cross(nb, nc) < -eps) return -1; // a,
  if (dot(nb, nc) < 0) return 2;       //
  if (norm(nb) < norm(nc)) return -2;  // 
  return 0;                          
}


bool isis_ll(const Line& l, const Line& m) {
  return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

bool isis_ls(const Line& l, const Line& s) {
  return isis_ll(l, s) &&
    (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}
bool isis_ss(const Line& s, const Line& t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
    ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

bool isis_lp(const Line& l, const Point& p) {
  return (abs(cross(l.b - p, l.a - p)) < eps);
}

bool isis_sp(const Line& s, const Point& p) {
  return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

Point proj(const Line &l, const Point& p) {
  ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + t * (l.a - l.b);
}

Point is_ll(const Line &s, const Line& t) {
  Point sv = s.b - s.a, tv = t.b - t.a;
  assert(cross(sv, tv) != 0);
  return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
vector<Point> is_ll2(const Line &s, const Line& t) {
  Point sv = s.b - s.a, tv = t.b - t.a;
  if (cross(sv, tv) != 0)return vector<Point>(1, is_ll(s, t));
  else {
    vector<Point>ans;
    for (int k = 0; k < 2; ++k) {
      if (isis_sp(s, t[k]) && find(ans.begin(), ans.end(), t[k]) == ans.end())ans.push_back(t[k]);
      if (isis_sp(t, s[k]) && find(ans.begin(), ans.end(), s[k]) == ans.end())ans.push_back(s[k]);
    }
    return ans;
  }
}
Point is_ss(const Line &s, const Line& t) {
  if (isis_ss(s, t)) {
    for (int k = 0; k < 2; ++k) {
      for (int l = 0; l < 2; ++l) {
        if (s[k] == t[l])return s[k];
      }
    }
    return is_ll(s, t);
  }
  else {
    assert(false);
    return Point(0, 0);
  }
}
ld dist_lp(const Line& l, const Point& p) {
  return abs(p - proj(l, p));
}

ld dist_ll(const Line& l, const Line& m) {
  return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

ld dist_ls(const Line& l, const Line& s) {
  return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

ld dist_sp(const Line& s, const Point& p) {
  Point r = proj(s, p);
  return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

ld dist_ss(const Line& s, const Line& t) {
  if (isis_ss(s, t)) return 0;
  return min({ dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b) });
}

Line bisection(const Line &s, const Line &t) {
  const Point laglanju(is_ll(s, t));
  const Point avec = !(abs(laglanju - s[0])<eps) ? s[0] - laglanju : s[1] - laglanju;
  const Point bvec = !(abs(laglanju - t[0])<eps) ? t[0] - laglanju : t[1] - laglanju;

  return Line(laglanju, laglanju + (abs(bvec)*avec + abs(avec)*bvec) / (abs(avec) + abs(bvec)));
}


Point  inner_center(const vector<Line>&ls) {
  vector<Point>vertics;
  for (int i = 0; i <static_cast<int>(ls.size()); ++i) {
    vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
  }
  if (vertics[0] == vertics[1] || vertics[1] == vertics[2] || vertics[2] == vertics[0])return vertics[0];
  Line bi1(bisection(Line(vertics[0], vertics[1]), Line(vertics[0], vertics[2])));
  Line bi2(bisection(Line(vertics[1], vertics[2]), Line(vertics[1], vertics[0])));
  if (bi1[0] == bi2[0])return bi1[0];
  else {
    return is_ll(bi1, bi2);
  }
}

vector<Point>  ex_center(const vector<Line>&ls) {
  vector<Point>vertics;
  for (int i = 0; i < static_cast<int>(ls.size()); ++i) {
    vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
  }
  if (abs(vertics[0] - vertics[1])<eps || abs(vertics[1] - vertics[2])<eps || (abs(vertics[2] - vertics[0])<eps))return vector<Point>();
  vector<Point>ecs;
  for (int i = 0; i < 3; ++i) {
    Line bi1(bisection(Line(vertics[i], vertics[i] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[i], vertics[(i + 1) % 3])));
    Line bi2(bisection(Line(vertics[(i + 1) % 3], vertics[(i + 1) % 3] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[(i + 1) % 3], vertics[i])));
    ecs.push_back(is_ll(bi1, bi2));
  }
  return ecs;
}


vector<Point>  same_dis(const vector<Line>&ls) {
  vector<Point>vertics;
  vertics.push_back(is_ll(ls[0], ls[2]));
  vertics.push_back(is_ll(ls[1], ls[2]));

  if (abs(vertics[0] - vertics[1]) < eps)return vector<Point>{vertics[0]};
  Line bis(bisection(ls[0], ls[1]));
  vector<Point>ecs;

  Line abi(bisection(Line(vertics[0], vertics[1]), ls[0]));
  ecs.push_back(is_ll(bis, abi));


  Line bbi(bisection(Line(vertics[0], 2.l*vertics[0] - vertics[1]), ls[0]));
  ecs.push_back(is_ll(bis, bbi));

  return ecs;
}
vector<Point> is_cc(const Circle& c1, const Circle& c2) {
  vector<Point> res;
  ld d = abs(c1.p - c2.p);
  ld rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  ld dfr = c1.r * c1.r - rc * rc;
  if (abs(dfr) < eps) dfr = 0.0;
  else if (dfr < 0.0) return res; // no intersection
  ld rs = sqrt(dfr);
  Point diff = (c2.p - c1.p) / d;
  res.push_back(c1.p + diff * Point(rc, rs));
  if (dfr != 0.0) res.push_back(c1.p + diff * Point(rc, -rs));
  return res;
}

int is_in_circle(const Circle &cir, const  Point& p) {
  ld dis = abs(cir.p - p);
  if (dis > cir.r + eps)return 0;
  else if (dis < cir.r - eps)return 2;
  else return 1;
}
int circle_in_circle(const Circle &lc, const  Circle&rc) {
  ld dis = abs(lc.p - rc.p);
  if (dis < rc.r - lc.r - eps)return 2;
  else if (dis>rc.r - lc.r + eps)return 0;
  else return 1;
}

vector<Point> is_lc(const Circle& c, const Line& l) {
  vector<Point> res;
  ld d = dist_lp(l, c.p);
  if (d < c.r + eps) {
    ld len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d); //safety;
    Point nor = (l.a - l.b) / abs(l.a - l.b);
    res.push_back(proj(l, c.p) + len * nor);
    res.push_back(proj(l, c.p) - len * nor);
  }
  return res;
}
vector<Point> is_sc(const Circle& c, const Line& l) {
  vector<Point> v = is_lc(c, l), res;
  for (Point p : v)
    if (isis_sp(l, p)) res.push_back(p);
  return res;
}

vector<Line> tangent_cp(const Circle& c, const Point& p) {
  vector<Line> ret;
  Point v = c.p - p;
  ld d = abs(v);
  ld l = sqrt(norm(v) - c.r * c.r);
  if (isnan(l)) { return ret; }
  Point v1 = v * Point(l / d, c.r / d);
  Point v2 = v * Point(l / d, -c.r / d);
  ret.push_back(Line(p, p + v1));
  if (l < eps) return ret;
  ret.push_back(Line(p, p + v2));
  return ret;
}

vector<Line> tangent_cc(const Circle& c1, const Circle& c2) {
  vector<Line> ret;
  if (abs(c1.p - c2.p) - (c1.r + c2.r) > -eps) {
    Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
    ret = tangent_cp(c1, center);
  }
  if (abs(c1.r - c2.r) > eps) {
    Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
    vector<Line> nret = tangent_cp(c1, out);
    ret.insert(ret.end(), ALL(nret));
  }
  else {
    Point v = c2.p - c1.p;
    v /= abs(v);
    Point q1 = c1.p + v * Point(0, 1) * c1.r;
    Point q2 = c1.p + v * Point(0, -1) * c1.r;
    ret.push_back(Line(q1, q1 + v));
    ret.push_back(Line(q2, q2 + v));
  }
  return ret;
}
ld two_circle_area(const Circle&l, const Circle&r) {
  ld dis = abs(l.p - r.p);
  if (dis > l.r + r.r)return 0;
  else if (dis + r.r < l.r) {
    return r.r*r.r*pi;
  }
  else if (dis + l.r < r.r) {
    return l.r*l.r*pi;
  }
  else {
    ld ans = (l.r)*(l.r)*acos((dis*dis + l.r*l.r - r.r*r.r) / (2 * dis*l.r)) +
      (r.r)*(r.r)*acos((dis*dis + r.r*r.r - l.r*l.r) / (2 * dis*r.r)) -
      sqrt(4 * dis*dis*l.r*l.r - (dis*dis + l.r*l.r - r.r*r.r)*(dis*dis + l.r*l.r - r.r*r.r)) / 2;
    return ans;
  }

}


typedef vector<Point> Polygon;

ld area(const Polygon &p) {
  ld res = 0;
  int n = p.size();
  REP(j, n) res += cross(p[j], p[(j + 1) % n]);
  return res / 2;
}

bool is_counter_clockwise(const Polygon &poly) {
  ld angle = 0;
  int n = poly.size();
  REP(i, n) {
    Point a = poly[i], b = poly[(i + 1) % n], c = poly[(i + 2) % n];
    angle += arg((c - b) / (b - a));
  }
  return angle > eps;
}

int is_in_polygon(const Polygon &poly, const  Point& p) {
  ld angle = 0;
  int n = poly.size();
  REP(i, n) {
    Point a = poly[i], b = poly[(i + 1) % n];
    if (isis_sp(Line(a, b), p)) return 1;
    angle += arg((b - p) / (a - p));
  }
  return eq(angle, 0) ? 0 : 2;
}
enum { OUT, ON, IN };
int convex_contains(const Polygon &P, const Point &p) {
  const int n = P.size();
  Point g = (P[0] + P[n / 3] + P[2 * n / 3]) / 3.0l; // inner-point
  int a = 0, b = n;
  while (a + 1 < b) { // invariant: c is in fan g-P[a]-P[b]
    int c = (a + b) / 2;
    if (cross(P[a] - g, P[c] - g) > 0) { // angle < 180 deg
      if (cross(P[a] - g, p - g) > 0 && cross(P[c] - g, p - g) < 0) b = c;
      else                                                  a = c;
    }
    else {
      if (cross(P[a] - g, p - g) < 0 && cross(P[c] - g, p - g) > 0) a = c;
      else                                                  b = c;
    }
  }
  b %= n;
  if (cross(P[a] - p, P[b] - p) < 0) return 0;
  if (cross(P[a] - p, P[b] - p) > 0) return 2;
  return 1;
}

Polygon convex_hull(vector<Point> ps) {
  int n = ps.size();
  int k = 0;
  sort(ps.begin(), ps.end());
  Polygon ch(2 * n);
  for (int i = 0; i < n; ch[k++] = ps[i++])
    while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--])
    while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  ch.resize(k - 1);
  return ch;
}



vector<Polygon> convex_cut(const Polygon &ps, const Line& l) {
  int n = ps.size();
  Polygon Q;
  Polygon R;
  REP(i, n) {
    Point A = ps[i], B = ps[(i + 1) % n];
    Line m = Line(A, B);
    if (ccw(l.a, l.b, A) != -1) Q.push_back(A);
    if (ccw(l.a, l.b, A) != 1) R.push_back(A);
    if (ccw(l.a, l.b, A) * ccw(l.a, l.b, B) < 0 && isis_ll(l, m)) {
      Q.push_back(is_ll(l, m));
      R.push_back(is_ll(l, m));
    }
  }
  const vector<Polygon>polys{ Q,R };
  return polys;
}


void add_point(vector<Point> &ps, const Point p) {
  for (Point q : ps) if (abs(q - p) < eps) return;
  ps.push_back(p);
}

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) { }
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

void add_edge(Graph &g, const int from, const int to, const Weight weight) {
  g[from].push_back(Edge{ from, to, weight });
}

Graph segment_arrangement(const vector<Line> &s, const vector<Point> &p) {
  int n = p.size(), m = s.size();
  Graph g(n);
  REP(i, m) {
    vector<pair<ld, int>> vec;
    REP(j, n) if (isis_sp(s[i], p[j]))
      vec.emplace_back(abs(s[i].a - p[j]), j);
    sort(ALL(vec));
    REP(j, vec.size() - 1) {
      int from = vec[j].second, to = vec[j + 1].second;
      add_edge(g, from, to, static_cast<Weight>(abs(p[from] - p[to])));
    }
  }
  return g;
}
Graph sennbunn_arrangement(const vector<Line>&s) {
  vector<Point>crss;
  for (int i = 0; i < static_cast<int>(s.size()); ++i) {
    for (int j = i + 1; j < static_cast<int>(s.size()); ++j) {
      if (isis_ss(s[i], s[j])) {
        crss.push_back(is_ll(s[i], s[j]));
      }
    }
  }
  for (int i = 0; i <static_cast<int>(s.size()); ++i) {
    crss.push_back(s[i][0]);
    crss.push_back(s[i][1]);
  }
  return segment_arrangement(s, crss);
}

//Graph circle_arrangement(const vector<Circle> &c, const vector<Point> &p) {
//	int n = p.size(), m = c.size();
//	Graph g(n);
//	REP(i, m) {
//		vector<pair<ld, int>> vec;
//		REP(j, n) if (abs(abs(c[i].p - p[j]) - c[i].r) < eps)
//			vec.emplace_back(arg(c[i].p - p[j]), j);
//		sort(ALL(vec));
//		REP(j, vec.size() - 1) {
//			int from = vec[j].second, to = vec[j + 1].second;
//			ld angle = vec[j + 1].first - vec[j].first;
//			add_edge(g, from, to, static_cast<Weight>(angle * c[i].r));
//		}
//		if (vec.size() >= 2) {
//			int from = vec.back().second, to = vec.front().first;
//			ld angle = vec.front().first - vec.back().first;
//			add_edge(g, from, to, static_cast<Weight>(angle * c[i].r));
//		}
//	}
//	return g;
//}


/* ????????°?????? */

// ?????????????????¢?????¢??¬??????????????????????????????????????°???????????????
// ?????´?????????????¨?????????§????????´????????????????¨?????????§???????????????
// ?????° polygon ??????vector<int> ??§??¨?????????????§???¢???????????§?????????
// vector<int> ??§??¨????????? ????§???¢???i???????????????????????????????????????p????????????????????§?????????
vector<vector<int>> polygon;
vector<int> seg2p[1024][1024];

//Graph dual_graph(const vector<Line> &s, const vector<Point> &p) {
//	int N = p.size();
//	polygon.clear();
//	REP(i, 1024) REP(j, 1024) seg2p[i][j].clear();
//	vector<vector<tuple<ld, int, bool>>> tup(N);
//	REP(i, s.size()) {
//		int a = -1, b = -1;
//		REP(j, N) if (abs(s[i].a - p[j]) < eps) a = j;
//		REP(j, N) if (abs(s[i].b - p[j]) < eps) b = j;
//		assert(a >= 0 && b >= 0);
//		tup[a].emplace_back(arg(s[i].b - s[i].a), b, false);
//		tup[b].emplace_back(arg(s[i].a - s[i].b), a, false);
//	}
//	REP(i, N) sort(ALL(tup[i]));
//	REP(i, N) {
//		REP(j, tup[i].size()) {
//			ld angle; int pos = j, from = i, to; bool flag;
//			tie(angle, to, flag) = tup[i][j];
//			if (flag) continue;
//			vector<int> ps;
//			while (!flag) {
//				ps.push_back(from);
//				get<2>(tup[from][pos]) = true;
//				seg2p[from][to].push_back(polygon.size());
//				seg2p[to][from].push_back(polygon.size());
//				angle += pi + eps;
//				if (angle > pi) angle -= 2 * pi;
//				auto it = lower_bound(ALL(tup[to]), make_tuple(angle, 0, false));
//				if (it == tup[to].end()) it = tup[to].begin();
//				from = to; tie(angle, to, flag) = *it;
//				pos = it - tup[from].begin();
//			}
//			polygon.push_back(ps);
//		}
//	}
//	Graph g(polygon.size());
//	REP(i, N) REP(j, i) {
//		if (seg2p[i][j].size() == 2) {
//			int from = seg2p[i][j][0], to = seg2p[i][j][1];
//			g[from].push_back(Edge{ from, to });
//			g[to].push_back(Edge{ to, from });
//		}
//	}
//	return g;
//}




int main() {
  
  int N; cin >> N;
  vector<Point>ps;
  for (int i = 0; i < N; ++i) {
    int x, y; cin >> x >> y;
    Point p(x, y);
    ps.push_back(p);
  }

  Point center = (ps[0] + ps[1]) / 2.l;
  bool ok = true;
  if (N % 2) {
    ok = false;
  }
  else {
    center = (ps[0] + ps[N/2]) / 2.l;
    
    for (int i = 0; i < N / 2; ++i) {
      Point kouho = (ps[ i] + ps[(i + N/2)%N]) / 2.l;
      if (abs(center - kouho) > eps)ok = false;
    }
  }
  if (ok)cout << setprecision(22) << fixed << center.real() << " " << center.imag() << endl;
  else cout << "NA" << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 27952
final_rank: 4

code_snippet: #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;
}
accuracy: 1
time_ms: 20
memory_kb: 3624
final_rank: 3

code_snippet: #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);
        p*=point(cos(eps),sin(eps));
    }

    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,100){
            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;
}
accuracy: 0.48214285714285715
time_ms: 10
memory_kb: 3556
final_rank: 10

code_snippet: #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 double eps=1e-9;
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<double> point;
typedef pair<point,point> line;
bool equal(const double x1,const 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()); }
double length(const point& a){ return abs(a); }
double distance(const point& a,const point& b){ return abs(a-b); }
double dot(const point& a,const point& b){ return a.real()*b.real()+a.imag()*b.imag(); }
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) {
    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);
}
double distanceLP(const line &l, const point& p){
    return abs(p - projection(l, p));
}
double distanceLL(const line &l, const line &m){
    return intersectLL(l, m) ? 0 : distanceLP(l, m.first);
}
double distanceLS(const line &l, const line &s){
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s.first), distanceLP(l, s.second));
}
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));
}
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);
}
// ????§???¢????¬?????????¢???
double area(const vector<point>& pol){
    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){
        double x,y;
        cin >> x >> y;
        p=point(x,y);
        p*=point(cos(eps),sin(eps));
    }

    const double s=area(ps);
    auto opt=[&](){
        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));
        double lb=0,ub=distanceLP(l,point(right,0));
        rep(i,0,50){
            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 double pi=3.14159265;
    rep(i,0,100000){
        const point tmp=ans+point(1,0)*point(cos(2*pi*i/100000),sin(2*pi*i/100000));
        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;
}
accuracy: 0.48214285714285715
time_ms: 20
memory_kb: 3468
final_rank: 11

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

typedef complex<double> P;
typedef pair<P,P> L; //Line, Segment

const int SPLIT = 10000;
const double EPS = 1e-9;

namespace std {
  bool operator < (const P& a, const P& b){
    return fabs(real(a)-real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
  }
}


namespace std {
  bool operator < (const L& a, const L& b){
    return abs(a.first-a.second) < abs(b.first-b.second);
  }
}

double dot(P a, P b){ return real(conj(a)*b); }
double cross(P a, P b){ return imag(conj(a)*b); }
double area(vector<P> v){
  double sum = 0.0;
  int n = v.size();
  for(int i=0;i<n;i++) sum += (real(v[i]) - real(v[(i+1)%n])) * (imag(v[i]) + imag(v[(i+1)%n]));
  return fabs(sum) / 2;
};

int ccw(P a, P b, P c){
  b -= a;
  c -= a;
  if(cross(b,c) > EPS) return 1; 
  if(cross(b,c) < -EPS) return -1;
  if(dot(b,c) < -EPS) return 2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

P crossPoint(L l, L m){
  double A = cross(l.second - l.first, m.second - m.first);
  double B = cross(l.second - l.first, l.second - m.first);
  if(fabs(A) < EPS && fabs(B) < EPS) return m.first;
  else if(fabs(A) >= EPS) return m.first + B / A * (m.second - m.first);
}

vector<P> convex_cut(const vector<P>& G, L l){
  vector<P> ans;
  for(int i=0;i<(int)G.size();i++){
    P A = G[i];
    P B = G[(i+1)%G.size()];
    if(ccw(l.first, l.second, A) != -1) ans.push_back(A);
    if(ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0)
      ans.push_back(crossPoint(L(A,B), l));
  }
  return ans;
}

double getAngle(P a,P b){
  return atan2(b.real()-a.real(),b.imag()-a.imag());
}

double getDeg(double a){
  return 180/M_PI*a;
}

bool eq(double a,double b){
  int k = (int)max(log10(a),log10(b));
  for(int i=0;i<k;i++){
    a/=10.0; b/=10.0;
  }
  //x  printf("%.6lf %.6lf\n",a , b );
  if( abs(a-b) < 1E-5 ) return true;
  return false;
}
int N;
vector<P> V;


int main(){
  cin >> N;
  for(int i=0;i<N;i++){
    int x,y;
    cin >> x >> y;
    V.push_back( P(x,y) );
  }

  double ar = area(V);
  if( ar < 0.0 ){
    reverse(V.begin(),V.end());
    ar = abs(ar);
  }

  vector<L> seg;
  for(int i=0;i<N;i++){
    int pr = (i+N-1)%N;
    int nd = (i+1)%N;
    P st = V[pr];
    P ed = V[nd];
    if( ccw(st,V[i],ed) != 1 ) continue;
    //cout << getDeg(st) << " "<< getDeg(ed) << endl;
    for(int j=0;j<SPLIT;j++){
      P h = (st+ed)/(double)2.0;

      L s = L(V[i],h);
      vector<P> r = convex_cut(V,s);
      double ret = area(r);

      //      cout << V[i] << " ->" << h << " "<< ret << endl;

      if( ret < ar/2.0 - EPS  ){
        st = h;
      }  else if( ret > ar/2.0 + EPS ){
        ed = h;
      } else {
        st = h; break;
      }
    }
    //      cout << V[i] << " -> " << st << endl;
    seg.push_back( L(V[i],st) );
  }

 sort(seg.rbegin(),seg.rend());
 P poin;
 P v1 = (seg[0].second - seg[0].first); 
 v1 = v1 / abs(v1);
 for(int i=1;i<(int)seg.size();i++){ 
   P v2 = (seg[i].second - seg[i].first);
   v2 = v2 / abs(v2);
   if( !( (eq(v1.real(),v2.real()) && eq(v1.imag(),v2.imag())) ||
          (eq(v1.real(),-v2.real()) && eq(v1.imag(),-v2.imag())) ) ){
     poin = crossPoint(seg[0],seg[i]);
     break;
   }
 }
 //x    cout << poin << endl;

  bool f = true;
  for(int i=0;i<N;i++){
    P p = V[i];
    P nex = V[(i+1)%N];
    P ks = (nex-p)/(double)SPLIT;
    for(int j=0;j<SPLIT;j++,p+=ks){
      L s = L(p,poin);
      vector<P> r = convex_cut(V,s);
      //     printf("%.10lf %.10lf\n",area(r), ar/2.0 );
      if( !eq(area(r),ar/2.0) ) f = false;
      if(!f) break;
    }
    if(!f) break;
  }

  if( f ) printf("%.10lf %.10lf\n",poin.real() , poin.imag() );
  else cout << "NA" << endl;

}
accuracy: 1
time_ms: 1990
memory_kb: 1304
final_rank: 5

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

typedef complex<double> P;
typedef pair<P,P> L; //Line, Segment

const int SPLIT = 10000;
const double EPS = 1e-9;

namespace std {
  bool operator < (const P& a, const P& b){
    return fabs(real(a)-real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
  }
}


double dot(P a, P b){ return real(conj(a)*b); }
double cross(P a, P b){ return imag(conj(a)*b); }
double area(vector<P> v){
  double sum = 0.0;
  int n = v.size();
  for(int i=0;i<n;i++) sum += (real(v[i]) - real(v[(i+1)%n])) * (imag(v[i]) + imag(v[(i+1)%n]));
  return fabs(sum) / 2;
};

int ccw(P a, P b, P c){
  b -= a;
  c -= a;
  if(cross(b,c) > EPS) return 1; 
  if(cross(b,c) < -EPS) return -1;
  if(dot(b,c) < -EPS) return 2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

P crossPoint(L l, L m){
  double A = cross(l.second - l.first, m.second - m.first);
  double B = cross(l.second - l.first, l.second - m.first);
  if(fabs(A) < EPS && fabs(B) < EPS) return m.first;
  else if(fabs(A) >= EPS) return m.first + B / A * (m.second - m.first);
}

vector<P> convex_cut(const vector<P>& G, L l){
  vector<P> ans;
  for(int i=0;i<(int)G.size();i++){
    P A = G[i];
    P B = G[(i+1)%G.size()];
    if(ccw(l.first, l.second, A) != -1) ans.push_back(A);
    if(ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0)
      ans.push_back(crossPoint(L(A,B), l));
  }
  return ans;
}

double getAngle(P a,P b){
  return atan2(b.real()-a.real(),b.imag()-a.imag());
}

double getDeg(double a){
  return 180/M_PI*a;
}

bool eq(double a,double b){
  int k = (int)max(log10(a),log10(b));
  for(int i=0;i<k;i++){
    a/=10.0; b/=10.0;
  }
  if( abs(a-b) < 1E-6 ) return true;
  return false;
}
int N;
vector<P> V;


int main(){
  cin >> N;
  for(int i=0;i<N;i++){
    int x,y;
    cin >> x >> y;
    V.push_back( P(x,y) );
  }

  double ar = area(V);
  if( ar < 0.0 ){
    reverse(V.begin(),V.end());
    ar = abs(ar);
  }

  vector<L> seg;
  for(int i=0;i<N;i++){
    int pr = (i+N-1)%N;
    int nd = (i+1)%N;
    P st = V[pr];
    P ed = V[nd];
    if( ccw(st,V[i],ed) != 1 ) continue;
    //cout << getDeg(st) << " "<< getDeg(ed) << endl;
    for(int j=0;j<SPLIT;j++){
      P h = (st+ed)/(double)2.0;

      L s = L(V[i],h);
      vector<P> r = convex_cut(V,s);
      double ret = area(r);

      //      cout << V[i] << " ->" << h << " "<< ret << endl;

      if( ret < ar/2.0 - EPS  ){
        st = h;
      }  else if( ret > ar/2.0 + EPS ){
        ed = h;
      } else {
        st = h; break;
      }
    }
    //        cout << V[i] << " -> " << st << endl;
    seg.push_back( L(V[i],st) );
    if( seg.size() == 2 ) continue;
  }
  P poin = crossPoint(seg[0],seg[1]);

  // cout << poin << endl;

  bool f = true;
  for(int i=0;i<N;i++){
    P p = V[i];
    P nex = V[(i+1)%N];
    P ks = (nex-p)/(double)SPLIT;
    for(int j=0;j<SPLIT;j++,p+=ks){
      L s = L(p,poin);
      vector<P> r = convex_cut(V,s);
      //     printf("%.10lf %.10lf\n",area(r), ar/2.0 );
      if( !eq(area(r),ar/2.0) ) f = false;
      if(!f) break;
    }
    if(!f) break;
  }

  if( f ) printf("%.10lf %.10lf\n",poin.real() , poin.imag() );
  else cout << "NA" << endl;

}
accuracy: 0.9285714285714286
time_ms: 1290
memory_kb: 1296
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
typedef complex<double> P;
 
const double eps = 1e-10;
 
bool equals(double a, double b, double eps = 1e-10) {
  return abs(a-b) < eps;
}
 
double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}
 
double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}
 
int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a,b) > eps) return 1;
  if(cross(a,b) < -eps) return -1;
  if(dot(a,b) < -eps) return 2;
  if(norm(b)-norm(a) > eps) return -2;
  return 0;
}
 
P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1)/cross(b, a);
}
 
double getArea(const vector<P> &ps) {
  int n = ps.size();
  double res = 0;
  for(int i = 0; i < ps.size(); ++i) {
    res += cross(ps[i], ps[(i+1)%n]);
  }
  return res / 2.0;
}
 
vector<P> convex_cut(vector<P> ps, P p1, P p2, int dir = -1) {
  vector<P> v;
  for(int i = 0; i < ps.size(); ++i) {
    P a = ps[i];
    P b = ps[(i+1)%ps.size()];
    if(ccw(p1, p2, a) != dir) v.push_back(a);
    if(ccw(p1, p2, a)*ccw(p1, p2, b) == -1)
      v.push_back(getCrossP(a, b, p1, p2));
  }
  return v;
}
 
int main() {
  int N; cin >> N;
  vector<P> ps(N);
  for(int i = 0; i < N; ++i) {
    cin >> ps[i].real() >> ps[i].imag();
  }
  if(getArea(ps) < 0) reverse(ps.begin(), ps.end());
  double S = getArea(ps);
  double x = 0, y = 0;
  for(int i = 0; i < N; ++i) {
    x += ps[i].real();
    y += ps[i].imag();
  }
  x /= N;
  y /= N;
  P g(x, y);
  bool flag = true;
  for(int k = 0; k < 100000; ++k) {
    double rad = (double)rand()/(double)RAND_MAX * (double)M_PI;
    P t = g + P(cos(rad), sin(rad));
    if(!equals(getArea(convex_cut(ps, g, t)), S/2.0, 1e-3)) {
      flag = false;
      break;
    }
  }
  if(flag) {
    printf("%.10f %.10f\n", g.real(), g.imag());
  } else {
    printf("NA\n");
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 1264
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
typedef complex<double> P;
 
const double eps = 1e-10;
 
bool equals(double a, double b, double eps = 1e-10) {
  return abs(a-b) < eps;
}
 
double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}
 
double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}
 
int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a,b) > eps) return 1;
  if(cross(a,b) < -eps) return -1;
  if(dot(a,b) < -eps) return 2;
  if(norm(b)-norm(a) > eps) return -2;
  return 0;
}
 
P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1)/cross(b, a);
}
 
double getArea(const vector<P> &ps) {
  int n = ps.size();
  double res = 0;
  for(int i = 0; i < ps.size(); ++i) {
    res += cross(ps[i], ps[(i+1)%n]);
  }
  return res / 2.0;
}
 
vector<P> convex_cut(vector<P> ps, P p1, P p2, int dir = -1) {
  vector<P> v;
  for(int i = 0; i < ps.size(); ++i) {
    P a = ps[i];
    P b = ps[(i+1)%ps.size()];
    if(ccw(p1, p2, a) != dir) v.push_back(a);
    if(ccw(p1, p2, a)*ccw(p1, p2, b) == -1)
      v.push_back(getCrossP(a, b, p1, p2));
  }
  return v;
}
 
int main() {
  int N; cin >> N;
  vector<P> ps(N);
  for(int i = 0; i < N; ++i) {
    cin >> ps[i].real() >> ps[i].imag();
  }
  if(getArea(ps) < 0) reverse(ps.begin(), ps.end());
  double S = getArea(ps);
  double x = 0, y = 0;
  for(int i = 0; i < N; ++i) {
    x += ps[i].real();
    y += ps[i].imag();
  }
  x /= N;
  y /= N;
  P g(x, y);
  bool flag = true;
  srand(time(NULL));
  for(int k = 0; k < 100000; ++k) {
    double rad = (double)rand()/(double)RAND_MAX * (double)M_PI;
    P t = g + P(cos(rad), sin(rad));
    if(!equals(getArea(convex_cut(ps, g, t)), S/2.0, 1e-2)) {
      flag = false;
      break;
    }
  }
  if(flag) {
    printf("%.10f %.10f\n", g.real(), g.imag());
  } else {
    printf("NA\n");
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 1264
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
typedef complex<double> P;
 
const double eps = 1e-10;
 
bool equals(double a, double b, double eps = 1e-10) {
  return abs(a-b) < eps;
}
 
double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}
 
double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}
 
int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a,b) > eps) return 1;
  if(cross(a,b) < -eps) return -1;
  if(dot(a,b) < -eps) return 2;
  if(norm(b)-norm(a) > eps) return -2;
  return 0;
}
 
P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1)/cross(b, a);
}
 
double getArea(const vector<P> &ps) {
  int n = ps.size();
  double res = 0;
  for(int i = 0; i < ps.size(); ++i) {
    res += cross(ps[i], ps[(i+1)%n]);
  }
  return res / 2.0;
}
 
vector<P> convex_cut(vector<P> ps, P p1, P p2, int dir = -1) {
  vector<P> v;
  for(int i = 0; i < ps.size(); ++i) {
    P a = ps[i];
    P b = ps[(i+1)%ps.size()];
    if(ccw(p1, p2, a) != dir) v.push_back(a);
    if(ccw(p1, p2, a)*ccw(p1, p2, b) == -1)
      v.push_back(getCrossP(a, b, p1, p2));
  }
  return v;
}
 
int main() {
  int N; cin >> N;
  vector<P> ps(N);
  for(int i = 0; i < N; ++i) {
    cin >> ps[i].real() >> ps[i].imag();
  }
  if(getArea(ps) < 0) reverse(ps.begin(), ps.end());
  double S = getArea(ps);
  double x = 0, y = 0;
  for(int i = 0; i < N; ++i) {
    x += ps[i].real();
    y += ps[i].imag();
  }
  x /= N;
  y /= N;
  P g(x, y);
  bool flag = true;
  srand(time(NULL));
  for(int k = 0; k < 100000; ++k) {
    double rad = (double)rand()/(double)RAND_MAX * (double)M_PI;
    P t = g + P(cos(rad), sin(rad));
    if(!equals(getArea(convex_cut(ps, g, t)), S/2.0, 1e-4)) {
      flag = false;
      break;
    }
  }
  if(flag) {
    printf("%.10f %.10f\n", g.real(), g.imag());
  } else {
    printf("NA\n");
  }
  return 0;
}
accuracy: 0.48214285714285715
time_ms: 20
memory_kb: 1256
final_rank: 8

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

typedef complex<double> P;

const double eps = 1e-10;

bool equals(double a, double b, double eps = 1e-10) {
  return abs(a-b) < eps;
}

double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}

double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}

int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a,b) > eps) return 1;
  if(cross(a,b) < -eps) return -1;
  if(dot(a,b) < -eps) return 2;
  if(norm(b)-norm(a) > eps) return -2;
  return 0;
}

P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1)/cross(b, a);
}

double getArea(const vector<P> &ps) {
  int n = ps.size();
  double res = 0;
  for(int i = 0; i < ps.size(); ++i) {
    res += cross(ps[i], ps[(i+1)%n]);
  }
  return res / 2.0;
}

vector<P> convex_cut(vector<P> ps, P p1, P p2, int dir = -1) {
  vector<P> v;
  for(int i = 0; i < ps.size(); ++i) {
    P a = ps[i];
    P b = ps[(i+1)%ps.size()];
    if(ccw(p1, p2, a) != dir) v.push_back(a);
    if(ccw(p1, p2, a)*ccw(p1, p2, b) == -1)
      v.push_back(getCrossP(a, b, p1, p2));
  }
  return v;
}

int main() {
  int N; cin >> N;
  vector<P> ps(N);
  for(int i = 0; i < N; ++i) {
    cin >> ps[i].real() >> ps[i].imag();
  }

  if(getArea(ps) < 0) reverse(ps.begin(), ps.end());
  double S = getArea(ps);

  double x, y;
  for(double l = 0.0, r = 1000000.0; x = (l+r) / 2.0, !equals(l, r);) {
    if(getArea(convex_cut(ps, P(x,0), P(x,1))) < S/2.0) {
      l = x;
    } else {
      r = x;
    }
  }
  for(double l = 0.0, r = 1000000.0; y = (l+r) / 2.0, !equals(l, r);) {
    if(getArea(convex_cut(ps, P(0,y), P(1,y))) < S/2.0) {
      r = y;
    } else {
      l = y;
    }
  }
  x = y = 0.0;
  for(int i = 0; i < N; ++i) {
    x += ps[i].real();
    y += ps[i].imag();
  }
  x /= N;
  y /= N;
  P g(x, y);
  bool flag = true;
  for(int k = 0; k < 100000; ++k) {
    double rad = (double)rand()/(double)RAND_MAX * (double)M_PI;
    P t = g + P(cos(rad), sin(rad));
    if(!equals(getArea(convex_cut(ps, g, t)), S/2.0, 1e-4)) {
      flag = false;
      break;
    }
  }
  if(flag) {
    printf("%.10f %.10f\n", g.real(), g.imag());
  } else {
    printf("NA\n");
  }
  return 0;
}
accuracy: 0.48214285714285715
time_ms: 30
memory_kb: 1256
final_rank: 9

code_snippet: #include<cstdio>
#include<iostream>
#include<complex>
#include<vector>
#include<algorithm>
#include<cmath>
#include<map>
#include<list>

#define EPS (1e-8)
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
#define pb push_back
#define sz size()
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

using namespace std;

typedef complex<long double> P;
typedef pair<P,P> L;
typedef vector<P> Poly;
typedef pair<P,long double> C;

const long double PI = acos(-1);

long double rabs(long double a,long double b){
  return abs(a-b)/a;
}

//for vector
P unit(P p){return p / abs(p);}

pair<P,P> norm(P p){return make_pair(p*P(0,1),p*P(0,-1));}

long double dot(P x,P y){return real(conj(x)*y);}

long double cross(P x,P y){return imag(conj(x)*y);}

//rotate a point counter-clockwise on the origin
P rotate(P v,long double s){
  return P(real(v)*cos(s) - imag(v)*sin(s), real(v)*sin(s) + imag(v)*cos(s) );
}

//return seta A
long double arg(P a,P b,P c){return acos(dot(b-a,c-a)/(abs(b-a)*abs(c-a)));}
long double arg(long double a,long double b,long double c){return acos( (b*b+c*c-a*a)/(2*b*c) );}


//for line(segment)
int ccw(P a,P b,P 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 (abs(b)<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

P line_cp(L a,L b){
  long double A = cross(b.sc-b.fs,b.fs-a.fs);
  long double B = cross(b.sc-b.fs,a.sc-a.fs);
  if(abs(A) < EPS){
    if(abs(B) < EPS)return a.fs; //same line
    //else assert(false);
  }
  return a.fs+(a.sc-a.fs)*A/B;
}

//for polygon

//all vertex is already sorted.
long double area(Poly p){
  if(p.size()<3)return 0;
  long double res = cross(p[p.size()-1],p[0]);
  for(int i=1;i<p.size();i++)res += cross(p[i-1],p[i]);
  return res/2;
}

//all vertex is already sorted.
Poly convex_cut(Poly p,L l){
  Poly res;
  int n = p.size();
  for(int i=0;i<n;i++){
    int nxt = (i+1)%n;
    if(ccw(l.fs,l.sc,p[i]) != -1)res.pb(p[i]);
    if(ccw(l.fs,l.sc,p[i]) * ccw(l.fs,l.sc,p[nxt]) < 0){
      res.pb( line_cp(l, L(p[i],p[nxt]) ) );
    }
  }
  return res;
}

int main(){
  int n;
  Poly p;

  scanf("%d",&n);
  p.resize(n);
  for(int i=0;i<n;i++)scanf("%Lf%Lf",&p[i].real(),&p[i].imag());
  long double s = area(p)/2;

  P a[2];
  long double lx = p[0].real(), ux = p[0].real(), ly = p[0].imag();
  for(int i=1;i<n;i++){
    lx = min(lx,p[i].real());
    ux = max(ux,p[i].real());
    ly = min(ly,p[i].imag());
  }
  a[0] = P(lx,ly-1e6); a[1] = P(ux,ly-1e6);

  L line[2];
  for(int i=0;i<2;i++){
    long double l = 0,r = PI,mid;
    P u = P(1,0);

    for(int j=0;j<1000;j++){
      mid = (l+r)/2;
      L tmp = L(a[i],a[i]+rotate(u,mid));
      long double cut = area(convex_cut(p,tmp));
      if(cut + EPS < s)r = mid;
      else l = mid;
    }
    line[i] = L(a[i],a[i]+rotate(u,l));
  }
  
  P res = line_cp(line[0],line[1]);
  
  for(int i=0;i<n;i++){
    L tmp = L(res,p[i]);
    Poly hoge = convex_cut(p,tmp);
    //printf("%.20Lf\n",area(convex_cut(p,tmp)));
    if(rabs(s, area(convex_cut(p,tmp))) > EPS){
      printf("NA\n");
      return 0;
    }
  }
  printf("%.8Lf %.8Lf\n",res.real(),res.imag());
}
accuracy: 0.9642857142857143
time_ms: 10
memory_kb: 1280
final_rank: 6