题目链接: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\n");
88 }
89 int main()
90 {
91     data_in();
92     work();
93     return 0;
94 }

View Code

转载于:https://www.cnblogs.com/KKKorange/p/8646447.html

BZOJ 4595 SHOI2015 激光发生器 射线,线段,偏转相关推荐

  1. BZOJ 2143 飞飞侠(线段树优化建边 / 并查集优化最短路)【BZOJ修复工程】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2143 是 hydro 的 BZOJ ...

  2. BZOJ.3165.[HEOI2013]Segment(李超线段树)

    BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ...

  3. BZOJ 1901 Dynamic Rankings(线段树+treap)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1901 题意:给出一个数列,两种操作:(1)询问区间第K小值:(2)修改某个位置的值. 思 ...

  4. BZOJ.2212.[POI2011]Tree Rotations(线段树合并)

    题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...

  5. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)

    题目链接 对于序列上每一段连续区间的数我们都可以动态开点建一棵值域线段树.初始时就是\(n\)棵. 对于每次操作,我们可以将\([l,r]\)的数分别从之前它所属的若干段区间中分离出来,合并. 对于升 ...

  6. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  7. BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)

    裸的线段树...因为数组开小了而一直RE..浪费了好多时间.. -------------------------------------------------------------------- ...

  8. [BZOJ 2957]楼房重建(线段树)

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

  9. BZOJ 4811 树链剖分+线段树

    思路: 感觉这题也可神了.. (还是我太弱) 首先发现每一位不会互相影响,可以把每一位分开考虑,然后用树链剖分或者LCT维护这个树 修改直接修改,询问的时候算出来每一位填0,1经过这条链的变换之后得到 ...

最新文章

  1. 说得太好了!阿里巴巴为什么不用 ZooKeeper 做服务发现?
  2. Linux下如何高效删除一个几十G的文本文件的最后一行或几行
  3. hdu3072 Intelligence System (最小树形图?)
  4. 一次Java解析数独的经历,java面试题,java高级笔试题
  5. 教你在 CentOS 8上安装GCC实现开发编译功能
  6. Android开发技术周报 Issue#101
  7. ISO15693协议RFID读卡器模块HX829的韦根66(WG66)通信协议说明
  8. 关于区块链你了解多少,用思维导图带你快速了解区块链
  9. php+mysql+jquery瀑布流
  10. 想转行学IT,到底要不要去培训机构?
  11. Spring事务(Transactions)的原理与实现
  12. 是什么撑起了极兔快递近200亿美元的估值?
  13. AI计算机视觉产品中长尾用户,基于长尾理论的AI写作具体分析
  14. linux服务器设置定时任务,Linux服务器定时任务
  15. 20万、50万、100万的算法工程师,有什么区别?
  16. windows下同一个显卡配置多个CUDA工具包以及它们之间的切换
  17. 2021年A股年度行情回顾与总结
  18. 全网最全pytest大型攻略,单元测试学这就够了
  19. csu1335 高桥与低桥
  20. matplotlib 饼图 plt.pie()

热门文章

  1. webform里的验证控件
  2. HTML教程--多页面窗体
  3. python读取csv文件第一行_尝试读取CSV文件的第一行返回['/']
  4. java怎么求两组整数的或集,确定整数是否在具有已知值集的两个整数(包括)之间的最快方法...
  5. fiddler抓包_Fiddler抓包详解
  6. java事件处理模型_从零开始理解JAVA事件处理机制(3)
  7. python如何保存列表_Python 基础知识全篇-列表(Lists)
  8. canal同步mysql到kafka_使用Canal同步MySQL数据到Kafka 得到的数据中sql字段无值-问答-阿里云开发者社区-阿里云...
  9. win7计算机创建新用户,win7系统无法创建新用户的解决方法
  10. c 语言 声明 定义,C/C++语言声明与定义详解