题目链接: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 ;
}

BZOJ 4595 SHOI2015 激光发生器 射线,线段,偏转的更多相关文章

  1. BZOJ 4592 SHOI2015 脑洞治疗仪 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4592 题意概述:需要维护一个01序列A,一开始A全部都是1.支持如下操作: 1.将区间[l ...

  2. bzoj 4595 激光发生器

    bzoj 4595 激光发生器 光线为射线,每次找到与当前光线相交且距离最近的镜子,然后旋转光线. 直线,射线利用线上一点+方向向量的方式表示.旋转时,旋转中心作为线上一点不变,方向向量左乘旋转矩阵. ...

  3. [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)

    [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...

  4. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  5. bzoj 4592(洛谷 4344) [Shoi2015]脑洞治疗仪——线段树上二分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4592 1操作就是用线段树来二分找到第一个有 k 个0的位置. 在洛谷上A了,与暴力和网上题解 ...

  6. bzoj 1537: [POI2005]Aut- The Bus 线段树

    bzoj 1537: [POI2005]Aut- The Bus 先把坐标离散化 设f[i][j]表示从(1,1)走到(i,j)的最优解 这样直接dp::: f[i][j] = max{f[i-1][ ...

  7. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  8. BZOJ.5286.[AHOI/HNOI2018]转盘(线段树)

    BZOJ LOJ 洛谷 如果从\(1\)开始,把每个时间\(t_i\)减去\(i\),答案取决于\(\max\{t_i-i\}\).记取得最大值的位置是\(p\),答案是\(t_p+1+n-1-p=\ ...

  9. BZOJ.4399.魔法少女LJJ(线段树合并)

    BZOJ 注意\(c\leq7\)→_→ 然后就是裸的权值线段树+线段树合并了. 对于取\(\max/\min\)操作可以直接区间修改清空超出范围的值,然后更新到对应位置上就行了(比如对\(v\)取\ ...

随机推荐

  1. data-ng-click 指令

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  2. o'Reill的SVG精髓(第二版)学习笔记——第三章

    第三章:坐标系统 3.1视口 文档打算使用的画布区域称作视口.我们可以在<svg>元素上使用width和height属性确定视口的大小.属性的值可以是一个数字,该数字会被当作用户坐标下的像 ...

  3. js使用hover事件做一个“个人中心”的浮动层

    原材料知识点:hover html: css:

  4. CALayer简介(转)

    一.简单介绍  在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮,一个文本标签,一个文本输入框,一个图标等等,这些都是UIView.  其实UIView之所以能显示在屏幕上,完全 ...

  5. iOS 崩溃日志分析(个人总结,最实用)

    iOS 崩溃日志分析(个人总结,最实用) 要分析奔溃日志需要三个文件:crash日志,symbolicatecrash分析工具,.dSYM符号集 0. 在桌面创建一个crash文件夹 1. 需要Xco ...

  6. c#本地缓存实现

    用了一段时间java,java实现服务端程序很简单,有很多公共开源的组件或者软件.但是c#的很少. 现在准备自己写点东西,学习下新的东西,总结下c#的内容以及我们经常用的内容,抽离成类,组件,模型.方 ...

  7. mybatis where in语句中参数过多

    ps : mybatis在in中参数过多 出现问题 com.microsoft.sqlserver.jdbc.SQLServerException: 传入的请求具有过多的参数.该服务器支持最多 210 ...

  8. PTA 最多删除3个字符(DP) - 30分

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输 ...

  9. ABAP术语-Connection Type

    Connection Type 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/17/1042479.html A connection ty ...

  10. vue过渡动画效果

    1 过渡基础 1.1 过渡的方式 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果. 包括以下工具: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS ...