HDU 5572 An Easy Physics Problem (计算几何 点类 线类 向量类 线段与圆相交)
来源:互联网 发布:网络语bug什么意思 编辑:程序博客网 时间:2024/05/21 06:00
题目链接
2015上海区域赛现场赛第5题 HDU5572
题目大意
光滑平面上,有一个固定的圆,圆外有两点A,B,问A以速度矢量V运动能否碰到B。(A碰到圆后会发生弹性碰撞)
分析
写这道题的时候没有想清楚就开始写了,比赛的时候一定要先把思路理清楚,情况比较多的题要画画树状图或者流程图。
看了一个大佬的博客中画了一个清晰的流程图,借鉴一下。
原博客链接
代码
#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>#include<map>#include<algorithm>#include<set>#include<stack>using namespace std;typedef long long int LL;typedef long double LD;const long double eps=1e-8;int dcmp(long double x){ if (fabs(x)<eps) return 0; if (x>0) return 1; return -1;}long double mysqrt(long double x){ return sqrt(max((long double)0,x));}struct Point ///点类{ long double x,y; Point() {} Point(long double a,long double b):x(a),y(b){} void input() { cin>>x>>y; } friend bool operator == (const Point &a,const Point &b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }};typedef Point Vector;///向量类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,long double t) {return Vector(A.x*t,A.y*t);}Vector operator / (Vector A,long double t) {return Vector(A.x/t,A.y/t);}long double dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}long double cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}long double length(Vector A) {return mysqrt(dot(A,A));}/*long double angle(Vector A,Vector B) {return acos(dot(A,B)/length(A)/length(B));}///求两向量夹角Vector Rotate(Vector A,long double rad)///向量A绕起点逆时针旋转rad弧度{ return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}*/struct Line///线类{ Point p; Vector v; Line (Point p,Vector v):p(p),v(v){} Point getPoint(long double t)///得到线上的一点 { return Point(p.x+t*v.x,p.y+t*v.y); }};Point project(Point A,Line L){ return L.p+L.v*(dot(L.v,A-L.p)/dot(L.v,L.v));}Point mirrorPoint(Point A,Line L){ Vector D=project(A,L); return D+(D-A);}void circle_cross_line(Point a,Point b,Point o,long double r,Point ret[],int &num)///求线段与圆交点模板{ long double x0=o.x,y0=o.y; long double x1=a.x,y1=a.y; long double x2=b.x,y2=b.y; long double dx=x2-x1,dy=y2-y1; long double A=dx*dx+dy*dy; long double B=2*dx*(x1-x0)+2*dy*(y1-y0); long double C=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)-r*r; long double delta=B*B-4*A*C; num=0; if (dcmp(delta)>=0) { long double t1=(-B-mysqrt(delta))/(2*A); long double t2=(-B+mysqrt(delta))/(2*A); if (dcmp(t1)>=0) ret[++num]=Point(x1+t1*dx,y1+t1*dy); if (dcmp(t2)>=0) ret[++num]=Point(x1+t2*dx,y1+t2*dy); }}int get_dis(Point a,Point b){ return ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}bool onRay(Point A,Line L)///判断点A是否在射线L(p,v)上{ Vector w=A-L.p; return (dcmp(cross(w,L.v))==0&&dcmp(dot(w,L.v))>0);}bool onSeg(Point A,Point B,Point C)///判断点A是否在线段BC上{ return (dcmp(cross(B-A,C-A))==0 && dcmp(dot(B-A,C-A))<0);}int main(){ int T,temp1,temp2,tot; Point O,A,AA,A1,B,C,ret[5],p1,p2,p3; Vector V; long double r; scanf("%d",&T); for (int tt=1;tt<=T;tt++) { printf("Case #%d: ",tt); O.input();cin>>r; A.input();V.input(); Line LA=Line(A,V); AA=LA.getPoint(1.0); B.input(); circle_cross_line(A,AA,O,r,ret,tot); if (tot==2&&ret[1]==ret[2])///用这个模板相同的交点会存两次 tot--; if (tot<=1)///如果圆没有改变A的运动轨迹(射线与圆相离或相切) { if (onRay(B,LA)) printf("Yes\n"); else printf("No\n"); continue; } temp1=get_dis(A,ret[1]); temp2=get_dis(A,ret[2]); if (temp1<temp2)///离A最近的那个交点为碰撞点C C=ret[1]; else C=ret[2]; if (onSeg(B,A,C))///如果B在线段AC上 printf("Yes\n"); else { Line OC=Line(O,C-O); A1=mirrorPoint(A,OC);///做A关于OC的对称点AC if (onRay(B,Line(C,A1-C)))///判断B是否在射线CA1上 printf("Yes\n"); else printf("No\n"); } } return 0;}
阅读全文
0 0
- HDU 5572 An Easy Physics Problem (计算几何 点类 线类 向量类 线段与圆相交)
- HDU 5572 An Easy Physics Problem【计算几何】
- HDU 5572 An Easy Physics Problem (物理、计算几何)
- HDU 5572 An Easy Physics Problem (计算几何+模板)
- HDU 5572-An Easy Physics Problem (计算几何)
- HDU5572 An Easy Physics Problem 【计算几何】
- hdu 5572 An Easy Physics Problem(几何)
- HDU 5572 An Easy Physics Problem(计算几何)——2015ACM/ICPC亚洲区上海站-重现赛
- hdu 5572 An Easy Physics Problem
- hdu 5572 An Easy Physics Problem
- HDU-5572-An Easy Physics Problem
- POJ 2826 An Easy Problem?! (计算几何、线段相交、思维)
- An Easy Physics Problem HDU
- [HDU 5572] An Easy Physics Problem (点在线上判定+对称)
- hdu5572An Easy Physics Problem+计算几何
- 计算几何 点线的综合题, 精度+ 线段相交+ 求交点 + 求面积 poj 2826 An Easy Problem?! (推荐)
- An Easy Physics Problem
- An Easy Problem?!(poj2826线段相交,直线线段相交)
- Java 基础抽象类
- html网页布局
- [跳出语句]goto、break、return、continue的理解
- < 笔记 > Git
- MFC简单自学图形绘制1
- HDU 5572 An Easy Physics Problem (计算几何 点类 线类 向量类 线段与圆相交)
- 警告自己
- JQuery与Ajax实现异步局部刷新
- cython初探
- android 补间动画
- 部落卫队问题
- linux中日志管理
- 链接器脚本
- 颜色空间:RGB,CMY,HSV,HSL,Lab详解