题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4595

题意概述:

  给出一条射线和N条线段,射线遇到线段会发生反射,令入射角alpha,出射角beta,则beta=alpha*phi_i(即对于每条线段phi是不同的),输出至多10条遇见的线段,没有发生相交的话输出NONE。

N<=100.

分析:

  实际上记得板子怎么打还是没什么问题的,问题就是我当时记不得了......

  还有一个事情,用余弦定理求两个向量夹角的时候记得-eps控制精度!

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
const double eps=1e-;
const double pi=acos(-1.0); int X,Y,dx,dy,N;
struct Point{
double x,y;
Point(){ }
Point(double xx,double yy){ x=xx,y=yy; }
}P[maxn]; int cnt=;
typedef Point Vector;
struct Line{
Point p; Vector v;
Line(){ }
Line(Point pp,Vector vv){ p=pp,v=vv; }
};
struct data{
int a,b;
Point p1,p2;
}A[maxn];
Vector operator + (const Vector &a,const Vector &b){ return Vector(a.x+b.x,a.y+b.y); }
Vector operator - (const Vector &a,const Vector &b){ return Vector(a.x-b.x,a.y-b.y); }
Vector operator * (const Vector &a,const double &b){ return Vector(a.x*b,a.y*b); }
int dcmp(double x){ return fabs(x)<eps?:(x>?:-); }
double Dot(const Vector &a,const Vector &b){ return a.x*b.x+a.y*b.y; }
double Cross(const Vector &a,const Vector &b){ return a.x*b.y-a.y*b.x; }
double Length(const Vector &a){ return sqrt(a.x*a.x+a.y*a.y); }
double Angle(const Vector &a,const Vector &b){ return acos(fabs(Dot(a,b))/Length(a)/Length(b)-eps); }
Vector Rotate(const Vector &v,const double &rad){
return Vector(v.x*cos(rad)-v.y*sin(rad),v.y*cos(rad)+v.x*sin(rad));
}
Point GetLineIntersection(const Line &a,const Line &b){
Vector u=a.p-b.p;
double t=Cross(b.v,u)/Cross(a.v,b.v);
return a.p+a.v*t;
}
bool Onsegment(const Point &p,const Point &a,const Point &b){
return dcmp(Dot(a-p,b-p))<=&&dcmp(Cross(a-p,a-p))==;
} void data_in()
{
scanf("%d%d%d%d%d",&X,&Y,&dx,&dy,&N);
for(int i=;i<=N;i++)
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);
}
void work()
{
int t=;
Point p=Point(X,Y),pp;
Vector v=Vector(dx,dy),vv;
while(t<=){
double md=1e9,dis; int id=;
for(int i=;i<=N;i++){
if(dcmp(Cross(A[i].p1-A[i].p2,v))==) continue;
pp=GetLineIntersection(Line(A[i].p1,A[i].p2-A[i].p1),Line(p,v));
if(Onsegment(pp,A[i].p1,A[i].p2)&&dcmp(Dot(v,pp-p))>){
dis=Length(p-pp);
if(dis<md) md=dis,id=i;
}
}
if(!id) break;
p=GetLineIntersection(Line(A[id].p1,A[id].p2-A[id].p1),Line(p,v));
if(dcmp(Dot(A[id].p1-A[id].p2,v))==) v=v*-;
else{
if(dcmp(Dot(A[id].p1-A[id].p2,v))>) vv=A[id].p1-A[id].p2;
else vv=A[id].p2-A[id].p1;
double alp=pi/-Angle(vv,v);
if(dcmp(Cross(vv,v))>) v=Rotate(vv,alp*A[id].a/A[id].b-pi/);
else v=Rotate(vv,pi/-alp*A[id].a/A[id].b);
}
printf("%d ",id);
t++;
}
if(t==) printf("NONE\n");
}
int main()
{
data_in();
work();
return ;
}

最新文章

  1. javascript中的变量作用域以及变量提升
  2. javascript中的对象
  3. Caliburn.Micro学习笔记(五)----协同IResult
  4. [Unity3d]3D项目转换为VR项目(暴风魔镜SDK)
  5. overlay-3
  6. STM8s窗口看门狗
  7. IP网络5种基本寻址方式 (单播、多播、广播、任播、地域多播)
  8. 关于XShell的常见使用和设置以及Linux中的常见命令.
  9. 使用 Python 开始游戏开发
  10. ES6就是ES2015 的主要内容
  11. Canvas基础讲义
  12. android动画介绍之 自定义Animation动画实现qq抖一抖效果
  13. hive笔记
  14. C#-基本语法(三)
  15. python数学第五天【常用概率分布】
  16. Delphi调用DLL中的接口
  17. Excel2010隔行变色的实现方法 [也可套用格式即可]
  18. 毒枭第一季/全集Narcos迅雷下载
  19. 【Python】Python文件系统功能:os模块
  20. HDUOJ -----免费馅饼

热门文章

  1. iOS之查看代码运行的时间
  2. Evercookie
  3. 记录JavaScript的util.js类库
  4. 【CodeForces 803 C】Maximal GCD(GCD+思维)
  5. HDFS的存储策略
  6. weex踩坑记录
  7. 监听浏览器返回,pushState,popstate 事件,window.history对象
  8. PHP实现微信红包算法和微信红包的架构设计简介
  9. mysql中tinyint、smallint、mediumint,int 和bigint 的区别
  10. Vue 服务器端渲染(一)