• BZOJ 4595 SHOI2015 激光发生器 射线,线段,偏转


    题目链接: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 }
    View Code
  • 相关阅读:
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    以太坊:通信协议对象 shh
    以太坊:Truffle 概述
    以太坊:快速入门 Truffle
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8646447.html
Copyright © 2020-2023  润新知