#include<cmath>
#include<cstdio>
#include<vector>
#include<cassert>
#include<cstdlib>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-8;
const double PI=acos(-1);

template<class T>
struct point{
	T x,y;
	point &operator+=(const point &a){ x+=a.x; y+=a.y; }
	point operator+(const point &a)const{ return (point){x+a.x,y+a.y}; }
	point operator-(const point &a)const{ return (point){x-a.x,y-a.y}; }
};

template<class T>
point<T> operator*(T c,const point<T> &a){ return (point<T>){c*a.x,c*a.y}; }

point<double> &operator/=(point<double> &a,double c){ a.x/=c; a.y/=c; return a; }

template<class T>
T cross(const point<T> &a,const point<T> &b){ return a.x*b.y-a.y*b.x; }

point<double> rot(const point<double> &a,double theta){
	return (point<double>){a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)};
}

template<class T>
struct line{ point<T> a,b; };

template<class T>
struct polygon:vector< point<T> >{
	polygon(){}
	polygon(int n):vector< point<T> >(n){}
};

enum {CCW=1,CW=-1,ON=0};
int ccw(const point<double> &a,const point<double> &b,const point<double> &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

point<double> get_intersect(const line<double> &L1,const line<double> &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a;
	return L2.a+a2/a1*(L2.b-L2.a);
}

template<class T>
polygon<double> convex_cut(const polygon<T> &G,const line<T> &L){
	int n=G.size();
	polygon<double> H;
	rep(i,n){
		int d1=ccw(L.a,L.b,G[i]);
		int d2=ccw(L.a,L.b,G[(i+1)%n]);
		if(d1!=CW) H.push_back(G[i]);
		if(d1==CCW && d2==CW || d1==CW && d2==CCW){
			H.push_back(get_intersect(L,(line<T>){G[i],G[(i+1)%n]}));
		}
	}
	return H;
}

point<double> center_of_gravity(const polygon<double> &G){
	point<double> g={0,0};
	rep(i,G.size()) g+=G[i];
	g/=G.size();
	return g;
}

int main(){
	const point<double> E={1,0};

	double w,h,e; scanf("%lf%lf%lf",&w,&h,&e); e*=PI/180;
	if(e<EPS){
		srand(77);
		double x1=rand()%100+rand()%100/100.,y1=rand()%100+rand()%100/100.;
		printf("? %.12f %.12f\n",x1,y1); fflush(stdout);
		double deg1; scanf("%lf",&deg1);
		double t1=deg1/180*PI;

		double x2=rand()%100+rand()%100/100.,y2=rand()%100+rand()%100/100.;
		printf("? %.12f %.12f\n",x2,y2); fflush(stdout);
		double deg2; scanf("%lf",&deg2);
		double t2=deg2/180*PI;

		point<double> p11={x1,y1},p12=p11+rot(E,t1);
		point<double> p21={x2,y2},p22=p21+rot(E,t2);
		point<double> ans=get_intersect((line<double>){p11,p12},(line<double>){p21,p22});
		printf("! %.12f %.12f\n",ans.x,ans.y); fflush(stdout);
	}
	else{
		polygon<double> G(4);
		G[0]=(point<double>){-w,-h};
		G[1]=(point<double>){ w,-h};
		G[2]=(point<double>){ w, h};
		G[3]=(point<double>){-w, h};

		rep(_,35){
			point<double> g=center_of_gravity(G);
			double phi[77],theta;
			rep(i,77){
				printf("? %.12f %.12f\n",g.x,g.y); fflush(stdout);
				scanf("%lf",phi+i); phi[i]*=PI/180;
				bool ok=false;
				rep(j,i+1) rep(k,i+1) if(j!=k) {
					double dif=phi[k]-phi[j];
					while(dif<0) dif+=2*PI;
					if(2*e-PI<dif && dif<2*PI-2*e) {
						ok=true;
						theta=phi[k]-e;
						goto FOUND;
					}
				}
			}

			FOUND:
			G=convex_cut(G,(line<double>){g,g+rot(E,theta)});
		}

		point<double> g=center_of_gravity(G);
		printf("! %.12f %.12f\n",g.x,g.y); fflush(stdout);
	}

	return 0;
}

Measured memory_bytes: 0