zoukankan      html  css  js  c++  java
  • An Easy Physics Problem HDU

    //#include<bits/stdc++.h>
    //#pragma comment(linker, "/STACK:1024000000,1024000000") 
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    
    const double pi=acos(-1.0);
    #define ll long long
    #define pb push_back
    
    const double eps=1e-6;
    
    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;}
    	double distance(Point p){
    		return hypot(x-p.x,y-p.y);
    	}
    	Point operator +(const Point &b)const{
    		return Point(x+b.x,y+b.y);
    	}
    	Point operator -(const Point &b)const{
    		return Point(x-b.x,y-b.y);
    	}
    	double operator *(const Point &b)const{
    		return x*b.x+y*b.y;
    	}
    	Point operator *(const double &k)const{
    		return Point(x*k,y*k);
    	}
    	Point operator /(const double &k)const{
    		return Point(x/k,y/k);
    	}
    	double operator^(const Point &b)const{
    		return x*b.y-y*b.x;
    	}
    	double len(){return hypot(x,y);}
    	double len2(){
    		return x*x+y*y;
    	}
    	Point trunc(double r){
    		double l=len();
    		if(!sgn(l))return *this;
    		r/=l;
    		return Point(x*r,y*r);
    	}
    };
    
    struct Line{
    	Point s,e;
    	Line(){}
    	Line (Point _s,Point _e){
    		s=_s;e=_e;
    	}
    	Line(Point p,double angle){//与x轴夹角
    		s=p;
    		if(sgn(angle-pi/2)==0)e=(s+Point(0,1));
    		else e=(s+Point(1,tan(angle)));
    	}
    	double length(){return s.distance(e);}
    	double dispointtoline(Point p){
    		return fabs((p-s)^(e-s))/length();
    	}
    	double dispointtoseg(Point p){
    		if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
    			return min(p.distance(s),p.distance(e));
    		return dispointtoline(p);
    	}
    	Point lineprog(Point p){
    		return s+( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
    	}
    };
    
    struct circle{
    	Point p;
    	double r;
    	circle(Point _p,double _r){
    		p=_p;r=_r;
    	}
    	int relationline(Line v){
    		double dst=v.dispointtoline(p);
    		if(sgn(dst-r)<0)return 2;
    		else if(sgn(dst-r)==0)return 1;
    		return 0;
    	}
    	int relationseg(Line v){
    		double dst=v.dispointtoseg(p);
    		if(sgn(dst-r)<0)return 2;
    		else if(sgn(dst-r)==0)return 1;
    		return 0;
    	}
    	int pointcrossline(Line v,Point &p1,Point &p2){
    		if(!(*this).relationline(v))return 0;
    		Point a=v.lineprog(p);
    		double d=v.dispointtoline(p);
    		d=sqrt(r*r-d*d);
    		if(sgn(d)==0){
    			p1=a;p2=a;return 1;
    		}
    		p1=a+(v.e-v.s).trunc(d);
    		p2=a-(v.e-v.s).trunc(d);
    		return 2;
    	}
    };
    
    int check(Point A,Point B,Point C){
    	if(B.x==C.x){
    		if((B.y-C.y)*(A.y-C.y)<0)return 1;
    		return 0;
    	}else if(B.y==C.y){
    		if( (B.x-C.x)*(A.x-C.x)<0)return 1;
    		return 0;
    	}
    	if( (B.x-C.x)*(A.x-C.x)<0 )return 1;
    	return 0;
    }
    
    
    int main(){
    	int T;
    	scanf("%d",&T);
    	int kase=0;
    	while(T--){
    		double x,y,r;
    		scanf("%lf%lf%lf",&x,&y,&r);
    		Point yuanxin=Point(x,y);
    		circle yuan=circle(yuanxin,r);		//圆柱 yuan
    		
    		Point A;
    		scanf("%lf%lf",&x,&y);A=Point(x,y);	//源点 A
    		double vx,vy;scanf("%lf%lf",&vx,&vy);
    		Line l1;
    		Point to;to=Point(vx+x,vy+y);
    		l1=Line(A,to);						//初始直线 l1
    
    		double bx,by;scanf("%lf%lf",&bx,&by);
    		Point B=Point(bx,by);				//终端 B
    
    		Point p1,p2;
    		
    		int xiangjiao=0;
    		xiangjiao=yuan.pointcrossline(l1,p1,p2);
    		
    		printf("Case #%d: ",++kase);
    
    		if(!xiangjiao){
    			if(fabs(l1.dispointtoline(B))<eps){
    			
    				if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){
    					printf("Yes
    ");
    				}else{
    					printf("No
    ");
    				}
    				continue;
    			}else printf("No
    ");
    		}else{	
    			//路径直线香蕉
    			//p1,p2是两个直线与圆的交点
    			//要靠近A的交点
    
    			Point bounce;
    			double dis1=(A.x-p1.x)*(A.x-p1.x)+(A.y-p1.y)*(A.y-p1.y);
    			double dis2=(A.x-p2.x)*(A.x-p2.x)+(A.y-p2.y)*(A.y-p2.y);
    			if(dis1<dis2)bounce=p1;else bounce=p2;				
    
    			Point C=bounce;
    			
    			int way=1;//速度指向圆
    
    			if(vx==0){
    				if( (C.y-A.y)*vy<0 )way=0;
    			}else if(vy==0){
    				if( (C.x-A.x)*vx<0)way=0;
    			}else{
    				if( (C.x-A.x)*vx<0 || (C.y-A.y)*vy<0)way=0;
    			}
    		//	cout<<way<<endl;
    			if(way==1){		//会反弹
    				
    				Line l2=Line(B,bounce);
    	
    				if(fabs(l1.dispointtoline(B))<eps){			
    
    					if(check(A,B,C)){
    						printf("No
    ");
    						continue;
    					}else{
    						printf("Yes
    ");
    						continue;
    					}
    				}else{			
    					if(yuan.relationseg(l2)>=2){
    						printf("No
    ");
    						continue;
    					}
    					
    
    					double d1=l1.dispointtoline(yuanxin);
    					double d2=l2.dispointtoline(yuanxin);
    
    					if(fabs(d1-d2)<eps){	//两个直线镜面
    						printf("Yes
    ");
    					}else printf("No
    ");
    				}
    
    			}else{
    				if(fabs(l1.dispointtoline(B))<eps){	
    					if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){
    						printf("Yes
    ");
    					}else{
    						printf("No
    ");
    					}
    					continue;
    				}else printf("No
    ");
    			}
    		}
    	}
    }

    QAQ !

    第一发计算几何题,WA5小时才过去

    自己的几何能力还是过得去的,很快想出了最复杂情况的做法

    (敲的时候把脑内秒过的简单情况给忘了QAQ

    不过因为第一次用模板,接口不熟,把自己坑爆了

    刚几何!

  • 相关阅读:
    codeforces 505E Mr. Kitayuta vs. Bamboos 题解
    codeforces 568C New Language 题解
    [AGC020E] Encoding Subsets 题解
    技巧瞎扯
    [AGC028C] Min Cost Cycle 题解
    [AGC018D] Tree and Hamilton Path 题解
    codeforces 1217D Coloring Edges 题解
    [AGC003C] BBuBBBlesort! 题解
    [AGC037C] Numbers on a Circle 题解
    [USACO09Open] Tower of Hay 题解
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611304.html
Copyright © 2011-2022 走看看