返回顶部

2015icpc上海

102 / 743 A HDU 5572 An Easy Physics Problem !!!

能踩的坑都踩了  太菜了
先看射线和圆是否相交 
不相交直接求解
否则算出A与圆的首个交点n
得出A的对称点 看B是否在反射的射线上即可
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double eps = 1e-8;
int sgn(double x){
	if(fabs(x)<eps) return 0;
	if(x<0) return -1;
	else return 1; 
}
struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x=_x;
		y=_y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("x=%lf y=%lf\n",x,y);
	}
	double len(){
		return sqrt(x*x+y*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);
	}
	double operator ^(const Point& b)const{
		return x*b.y-y*b.x;
	}
	double operator *(const Point &b)const{
		return x*b.x+y*b.y;
	}
	double dis(Point a){
		return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
	}
};
struct circle{
	Point o;
	double r;
	circle(){}
	void input(){
		o.input();
		scanf("%lf",&r);
	}
};
int main(){
	int t;
	scanf("%d",&t);
	int ca=0;
	while(t--){
		circle g;
		Point A,B;
		g.input();A.input();
		double Vx,Vy;
		scanf("%lf%lf",&Vx,&Vy);
		B.input();
		printf("Case #%d: ",++ca);
		double a=Vx*Vx+Vy*Vy;
		double b=2.0*(A.x*Vx+A.y*Vy-Vx*g.o.x-Vy*g.o.y);
		double c=-2.0*(A.x*g.o.x+A.y*g.o.y)+g.o.x*g.o.x+g.o.y*g.o.y-g.r*g.r+A.x*A.x+A.y*A.y;
		double xt=b*b-4.0*a*c;
		double x1=(-b-sqrt(xt))/(2.0*a),x2=(-b+sqrt(xt))/(2.0*a);
		if(sgn(xt)<=0||(sgn(x1)<0&&sgn(x2)<0)){
			int flag=1;
			double d1,d2;
			Point Q=(B-A);
			if(Vx==0){
				d2=Q.y/Vy;
				if(sgn(Q.x)!=0||sgn(d2)<0) flag=0;
			}else if(Vy==0){
				d1=Q.x/Vx;
				if(sgn(Q.y)!=0||sgn(d1)<0) flag=0;
			}else{
				d2=Q.y/Vy;
				d1=Q.x/Vx;
				if(sgn(d1-d2)!=0||sgn(d1)<0) flag=0;
			}
			if(flag) puts("Yes");
			else puts("No");
			continue;
		}
		Point o=g.o;
		Point n,ng,n2;
		//printf("x1=%lf x2=%lf\n",x1,x2);
		n=(A+Point(Vx*x1,Vy*x1));
		n2=(A+Point(Vx*x2,Vy*x2));
		//n.output(),n2.output();
		if(sgn((A-B)^(n-B))==0&&sgn((A-B)*(n-B))<=0){
			puts("Yes");
			continue;
		}
	//	printf("n.x=%lf n.y=%lf\n",n.x,n.y);
		double aa=o.y-n.y,bb=n.x-o.x,cc=o.x*n.y-o.y*n.x;
		double k,d,x0,y0;
		if(sgn(aa)==0){
			ng=Point(A.x,2.0*o.y-A.y);
		}else if(sgn(bb)==0){
			ng=Point(2.0*o.x-A.x,A.y);
		}else{
			k=-(aa/bb);
			d=-(cc/bb);
			x0=(A.x-k*d+k*A.y)/(1.0+k*k);
			y0=x0*k+d;
			ng=Point(2.0*x0,2.0*y0)-A;
		}
		//printf("a.x=%lf ng.x=%lf a.y=%lf ng.y=%lf sum=%lf\n",A.x,ng.x,A.y,ng.y,aa*(A.x+ng.x)+bb*(A.y+ng.y)+2.0*cc);
		if(sgn((B-n)^(ng-n))==0&&sgn((B-n)*(ng-n))>=0){
			puts("Yes");
		}else{
			puts("No");
		}
	}
	return 0;
}
/*
33
0 0 1 
-2 1 1 -1
-2 -1

0 0 1
-3 2 1 -1
-2 1

0 0 2
-2 1 1 0
0 5
*/
111 / 170  B    HDU 5573  Binary Tree                +++
     1 / 14     C     HDU 5574 Colorful Tree              ???
     27 / 170  D     HDU 5575  Discover Water Tank        ???
      10 / 49    E     HDU 5576  Expection of String        ???
200 / 237  F     HDU 5578  Friendship of Frog         ---
       5 / 125    G    HDU 5579 Game of Arrays             ???
       0 / 4      H     HDU 5580 Happiness of Frog          ???
       4 / 57     I     HDU 5581  Infinity Point Sets        ???
       1 / 51     J     HDU 5582  Journey of Taku            ???
 189 / 463  K     HDU 5583  Kingdom of Black and White ---
 175 / 373  L     HDU 5584 LCM Walk                   ---
posted @ 2021-02-07 00:00  League-of-cryer  阅读(85)  评论(0)    收藏  举报