首页 > 代码库 > ZOJ 3728 Collision
ZOJ 3728 Collision
---恢复内容开始---
今天无事水一水,结果就看到这个水题了!
题意思是 有俩个区域如图
求在俩个圆之间的运动时间 给出 初始的开始点和速度的矢量式;而且这个点 不再俩个圆之间的区域,且碰到内测员会反弹:
其实就是求 与俩个圆的交点! 代码如下:()
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <cstdio> using namespace std; struct point { double x,y; point ( double x=0, double y=0):x(x),y(y){} void show() { printf ( "%lf %lf\n" ,x,y); } }; typedef point Vector; const double eps=1e-8; int dcmp( double x) { if ( fabs (x)<eps) return 0; return x<0?-1:1; } Vector operator + (Vector a,Vector b){ return Vector(a.x+b.x,a.y+b.y);} Vector operator - (Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y);} Vector operator * (Vector a, double b){ return Vector(a.x*b,a.y*b);} double operator / (Vector a,Vector b){ if (dcmp(b.x)!=0) return a.x/b.x; return a.y/b.y;} double det(Vector a,Vector b){ return a.x*b.y-a.y*b.x;} double dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y;} double lenth(Vector a){ return sqrt (dot(a,a));} struct line { point p; Vector v; double angle; line(){} line(point p,Vector v):p(p),v(v){} bool operator <( const line &rht) const { return angle<rht.angle; } }; struct circle { point c; double r; circle(){c=point(0.0,0.0);} circle(point c, double r):c(c),r(r){} point Point( double rad) { return point(c.x+ cos (rad)*r,c.y+ sin (rad)*r); } }; int get_circle_intersection(line L,circle C, double &t1, double &t2) { t1=t2=0; double a=L.v.x, b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y; double e=a*a+c*c,f=2*(a*b+c*d),g=b*b+d*d-C.r*C.r; double detle = f*f-4*e*g; if (dcmp(detle)<0) return 0; if (dcmp(detle)==0) {t1=t2=-f/(2*e); return 1;} t1=(-f- sqrt (detle)) /(2*e); t2=(-f+ sqrt (detle)) /(2*e); if (dcmp(t1)<0 || dcmp(t2)<0) return 0; //按照速度的反方向才可以 return 2; } int main() { double t1,t2; double x1,x2; line tmp; circle tmp1; circle tmp2; double Rm, R, r; while (~ scanf ( "%lf %lf %lf %lf %lf %lf %lf" ,&Rm,&R,&r,&tmp.p.x,&tmp.p.y,&tmp.v.x,&tmp.v.y)) { Rm+=r;R+=r; tmp1.r=Rm; tmp2.r=R; int count1=get_circle_intersection(tmp,tmp1,t1,t2); int count2=get_circle_intersection(tmp,tmp2,x1,x2); if (count2==0) printf ( "0.00\n" ); else printf ( "%.3lf\n" , fabs (x2-x1)- fabs (t1-t2)); // 因为直线式点+向量(和速度一样)所以减法就可以了 } return 0; } |
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。