ZOJ 3226 Mobile Positioning

29 篇文章 0 订阅
2 篇文章 0 订阅

Link To The Problem


Solution : 

Step 1 : 求出B点的坐标(注意时间可能为0)

Step 2 : 求出A点的坐标


PS:一定要注意所有可能的情况。。。极其猥琐。。。


Code : 

// ZOJ 3226 Mobile Positioning
// Geometry & Math Calculate

#include<cstdio>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define sf scanf
#define pf printf
#define dbg(x) cerr << __LINE__ << " : " << #x << " : " << (x) << endl

typedef double D;

D const eps = 1.0e-6;
D const pi = acos(-1.0);

// Data Struct :

int inline dcmp(D x) {
	if(x>=-eps && x<=eps) return 0;
	return x > 0 ? 1 : -1;
}
D inline sqr(D x) { return x*x; }

struct P {
	D x,y;
	P() {};
	P(D x,D y):x(x),y(y){};
	P operator + (P u) {return P(x+u.x,y+u.y);} 
	P operator - (P u) {return P(x-u.x,y-u.y);}
	P operator * (D k) {return P(x*k, y*k);}
	P operator / (D k) {return P(x/k,y/k);}
	D operator * (P u) {return x*u.y-y*u.x;}
	D operator ^ (P u) {return x*u.x+y*u.y;}

	bool operator < (const P& u) const{ 
		if(dcmp(x-u.x) == 0) return dcmp(y-u.y) < 0;
		return dcmp(x-u.x) < 0;
	}
	bool operator == (const P& u) {
		return dcmp(x-u.x)==0 && dcmp(y-u.y)==0;
	}

	void read() { sf("%lf%lf",&x,&y); }
	void out() { 
		if(x<0 && -x < 0.005) x=0;
		if(y<0 && -y < 0.005) y=0;
		pf("%.2lf %.2lf\n",x,y);
   	}
	D len() { return sqrt(x*x+y*y); }
	P unit() { P ret(x,y);if(dcmp(ret.len())) ret=ret/ret.len();return ret;}
	P rotate(D s) { 
		return P(x*cos(s) - y*sin(s),
				 x*sin(s) + y*cos(s));
	}						
};

struct C {
	P u;
	D r;
	C() {};
	C(P u,D r):u(u),r(r){};
};

int intersection(C a,C b,P& p1,P& p2) {
	if(dcmp(a.r)==0) {
		p1 = a.u;
		return 1;
	}
	if(dcmp(b.r)==0) {
		p1 = b.u;
		return 1;
	}
	D d = (a.u-b.u).len();
	if(dcmp(d)==0 && dcmp(a.r-b.r)==0) return -1;
	if(dcmp(d-(a.r+b.r))>0) return 0;
	if(dcmp(d-fabs(a.r-b.r))<0) return 0;
	P dir = b.u-a.u;
	D s = acos((sqr(dir.len())+sqr(a.r)-sqr(b.r))/2.0/a.r/dir.len());
	dir = dir.unit();
	p1 = dir.rotate(s)*a.r + a.u;
	p2 = dir.rotate(-s)*a.r + a.u;
	if(p1 == p2) return 1;
	return 2;
}



// Soulution Part:

D t1,t2,t3,t4,v;
P B[2];
P P1,P2;
P ans[10];
int vis[10];

void work(){

	int num = 0;
	C c1(P1,t2*v),c2(P2,t3*v);
	if(dcmp(t1+t2)==0) {
		pf("1\n");
		P1.out();
		return ;
	}
	if(dcmp(t3+t4)==0) {
		pf("-1\n");
		return ;
	}
	D t = (t3+t4)/(t1+t2);

	int k = intersection(c1,c2,B[0],B[1]);
	if(k==-1) {
		pf("-1\n");
		return ;
	}
	for(int i=0;i<k;i++) {
		c1 = C(P1,t1*v);
		c2 = C(B[i]*((1+t)/t)-P2/t,t4*v/t);
		int k1=intersection(c1,c2,ans[num],ans[num+1]);
	//	dbg(k1);
		if(k1==-1) {
			pf("-1\n");
			return ;
		}
		num += k1;
	}

	memset(vis,0,sizeof(vis));
	int cnt = 0;
	P tmp[10];
	for(int i=0;i<num;i++) if(!vis[i]){
		for(int j=i+1;j<num;j++) if(ans[i]==ans[j]){
			vis[j]=1;
		}
		tmp[cnt++]=ans[i];
	}
	sort(tmp,tmp+cnt);
	pf("%d\n",cnt);
	for(int i=0;i<cnt;i++) tmp[i].out();
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif

	while(~sf("%lf%lf",&P1.x,&P1.y)){
		P2.read();
		sf("%lf%lf%lf%lf%lf",&t1,&t2,&t3,&t4,&v);
		work();
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值