题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4595
题意概述:
给出一条射线和N条线段,射线遇到线段会发生反射,令入射角alpha,出射角beta,则beta=alpha*phi_i(即对于每条线段phi是不同的),输出至多10条遇见的线段,没有发生相交的话输出NONE。
N<=100.
分析:
实际上记得板子怎么打还是没什么问题的,问题就是我当时记不得了......
还有一个事情,用余弦定理求两个向量夹角的时候记得-eps控制精度!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<cctype> 12 using namespace std; 13 const int maxn=105; 14 const double eps=1e-8; 15 const double pi=acos(-1.0); 16 17 int X,Y,dx,dy,N; 18 struct Point{ 19 double x,y; 20 Point(){ } 21 Point(double xx,double yy){ x=xx,y=yy; } 22 }P[maxn]; int cnt=0; 23 typedef Point Vector; 24 struct Line{ 25 Point p; Vector v; 26 Line(){ } 27 Line(Point pp,Vector vv){ p=pp,v=vv; } 28 }; 29 struct data{ 30 int a,b; 31 Point p1,p2; 32 }A[maxn]; 33 Vector operator + (const Vector &a,const Vector &b){ return Vector(a.x+b.x,a.y+b.y); } 34 Vector operator - (const Vector &a,const Vector &b){ return Vector(a.x-b.x,a.y-b.y); } 35 Vector operator * (const Vector &a,const double &b){ return Vector(a.x*b,a.y*b); } 36 int dcmp(double x){ return fabs(x)<eps?0:(x>0?1:-1); } 37 double Dot(const Vector &a,const Vector &b){ return a.x*b.x+a.y*b.y; } 38 double Cross(const Vector &a,const Vector &b){ return a.x*b.y-a.y*b.x; } 39 double Length(const Vector &a){ return sqrt(a.x*a.x+a.y*a.y); } 40 double Angle(const Vector &a,const Vector &b){ return acos(fabs(Dot(a,b))/Length(a)/Length(b)-eps); } 41 Vector Rotate(const Vector &v,const double &rad){ 42 return Vector(v.x*cos(rad)-v.y*sin(rad),v.y*cos(rad)+v.x*sin(rad)); 43 } 44 Point GetLineIntersection(const Line &a,const Line &b){ 45 Vector u=a.p-b.p; 46 double t=Cross(b.v,u)/Cross(a.v,b.v); 47 return a.p+a.v*t; 48 } 49 bool Onsegment(const Point &p,const Point &a,const Point &b){ 50 return dcmp(Dot(a-p,b-p))<=0&&dcmp(Cross(a-p,a-p))==0; 51 } 52 53 void data_in() 54 { 55 scanf("%d%d%d%d%d",&X,&Y,&dx,&dy,&N); 56 for(int i=1;i<=N;i++) 57 scanf("%lf%lf%lf%lf%d%d",&A[i].p1.x,&A[i].p1.y,&A[i].p2.x,&A[i].p2.y,&A[i].a,&A[i].b); 58 } 59 void work() 60 { 61 int t=1; 62 Point p=Point(X,Y),pp; 63 Vector v=Vector(dx,dy),vv; 64 while(t<=10){ 65 double md=1e9,dis; int id=0; 66 for(int i=1;i<=N;i++){ 67 if(dcmp(Cross(A[i].p1-A[i].p2,v))==0) continue; 68 pp=GetLineIntersection(Line(A[i].p1,A[i].p2-A[i].p1),Line(p,v)); 69 if(Onsegment(pp,A[i].p1,A[i].p2)&&dcmp(Dot(v,pp-p))>0){ 70 dis=Length(p-pp); 71 if(dis<md) md=dis,id=i; 72 } 73 } 74 if(!id) break; 75 p=GetLineIntersection(Line(A[id].p1,A[id].p2-A[id].p1),Line(p,v)); 76 if(dcmp(Dot(A[id].p1-A[id].p2,v))==0) v=v*-1; 77 else{ 78 if(dcmp(Dot(A[id].p1-A[id].p2,v))>0) vv=A[id].p1-A[id].p2; 79 else vv=A[id].p2-A[id].p1; 80 double alp=pi/2-Angle(vv,v); 81 if(dcmp(Cross(vv,v))>0) v=Rotate(vv,alp*A[id].a/A[id].b-pi/2); 82 else v=Rotate(vv,pi/2-alp*A[id].a/A[id].b); 83 } 84 printf("%d ",id); 85 t++; 86 } 87 if(t==1) printf("NONE "); 88 } 89 int main() 90 { 91 data_in(); 92 work(); 93 return 0; 94 }