题目链接:点击查看

题目大意:给出一个等边三角形的区域,再给出初始时一个质点的位置 ( x , y ) 和初始速度 ( vx , vy ) ,现在质点会不断运动,当碰到三角形的内壁时会根据角度反弹,问小球第 k 次碰到三角形的内壁的时间

题目分析:k 非常大,肯定不能暴力去模拟每一次小球的运动,借用题解的一句话更好理解:

灵感来自用激光笔往镜子中射入激光被多次反射。
人眼从激光笔的视角来看,光束并没有被 “反射”,而是穿入了 “镜子中的世界”。

将二维平面视为无穷大,大概就是这样互相拼接而成的等边三角形假设点 A 为起点,点 B 为一段时间后到达的位置,则线段 AB 穿过的三角形的边数,就是质点碰撞三角形内壁的次数了

这样一来,可以二分时间,然后去检查线段穿过的次数与题目中给出 k 的关系,当然,计算穿过的边数也是有技巧的,如果硬算投影的话应该也是可以的,只是比较麻烦,首先考虑如果只是计算穿过的蓝色线段的数量,可以直接根据 y 的值稍加计算得到,同理,可以旋转一下坐标系,这样就能很方便的求出穿过黄色和红色直线的条数了

借用一下大佬博客的图片:https://blog.csdn.net/jk_chen_acmer/article/details/107641065

像上面一样,每次逆时针旋转 120 度即可

注意一下,因为我们在旋转后,想要使得初始的三角形的三条边位于 x 轴上,所以初始点 P 是围绕着三角形的中心旋转的,而速度向量是 V - O 构成的,换句话说,需要将点 V 和点 O 分别旋转后再做减法得到向量(这样操做或许比较麻烦,但个人看来是最容易理解的)

因为在进行上述旋转后,有一个好处就是,初始时的点 P 的 y 坐标一定是大于 0 的,所以此时对于运动停止时的点 Q ,我们分两种情况讨论:

  1. Q.y > 0:Q 和 P 位于 x 轴的同一侧,此时答案为
  2. Q.y < 0:Q 和 P 位于 x 轴的不同侧,需要加上 y = 0 这条直线,此时答案为(因为 Q.y 是小于 0 的,所以需要减)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;const double eps = 1e-8;const double pi = acos(-1.0);int sgn(double x){if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}struct Point{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}bool operator == (Point b)const{return sgn(y-b.y) == 0;}bool operator < (Point b)const{return sgn(y-b.y)<0;}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}Point operator *(const double &k)const{return Point(x*k,y*k);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}//返回两点的距离double distance(Point p){return hypot(x-p.x,y-p.y);}//`绕着p点逆时针旋转angle`Point rotate(Point p,double angle){Point v = (*this) - p;double c = cos(angle), s = sin(angle);return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);}
};double L,x,y,vx,vy,h;int k;Point P[4],Q[4],V[4],O[4],T;LL cal(double t,int i)
{Point Q=P[i]+V[i]*t;if(sgn(Q.y)>=0)return (LL)floor(Q.y/h);elsereturn 1LL-(LL)ceil(Q.y/h);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%lf%lf%lf%lf%lf%d",&L,&x,&y,&vx,&vy,&k);h=sqrt(3)*L/2.0;T=Point(0,h/3.0);//中心点O[1]=Point(0,0),O[2]=O[1].rotate(T,pi*2.0/3.0),O[3]=O[1].rotate(T,pi*4.0/3.0);//原点P[1]=Point(x,y),P[2]=P[1].rotate(T,pi*2.0/3.0),P[3]=P[1].rotate(T,pi*4.0/3.0);//初始点V[1]=Point(vx,vy),V[2]=V[1].rotate(T,pi*2.0/3.0),V[3]=V[1].rotate(T,pi*4.0/3.0);//速度向量for(int i=1;i<=3;i++)V[i]=V[i]-O[i];//得到速度向量double l=0,r=1e10,ans;while(fabs(l-r)>=1e-5){double mid=(l+r)*0.5;if(cal(mid,1)+cal(mid,2)+cal(mid,3)>=k){ans=mid;r=mid;}elsel=mid;}printf("%.10f\n",ans);}return 0;
}

HDU多校3 - 6798 Triangle Collision(几何+旋转坐标系)相关推荐

  1. CodeForces - 123B Squares(简单几何+旋转坐标系)

    题目链接:点击查看 题目大意:给出一个无限大的二维坐标平面,现在有一些坏点,规定: 满足以上两条件之一的点即为坏点,现在问最少经过多少个坏点的情况下,可以从起点到达终点 题目分析:一开始没想到坏点是如 ...

  2. 权值线段树小结(hdu多校,普通平衡树,郁闷的出纳员)

    之前刷了一点主席树的题目,但是没有系统的做过权值线段树的题目.主席树是多根权值线段树的综合.权值线段树可以解决在总区间里求第k大的问题.在普通的线段树里,我们每一个节点维护的是权值大小.但是在权值线段 ...

  3. HDU 多校 6400 Parentheses Matrix(构造)

    HDU 多校 6400 Parentheses Matrix(构造) // Problem: D. Parentheses Matrix // Contest: Codeforces - 2018 C ...

  4. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

  5. HDU多校4 - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?!(单调栈)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问给出一个区间 [l,r][l,r][l,r],要求输出区间 [l,r][l,r][l,r] 内 " ...

  6. HDU多校4 - 6992 Lawn of the Dead(线段树+模拟)

    题目链接:点击查看 题目大意:给出一个 n∗mn*mn∗m 的矩阵,有 kkk 个点被 banbanban 掉了,现在从点 (1,1)(1,1)(1,1) 出发,只能向右或向下移动,问可以到达的点有多 ...

  7. HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)

    题目链接:点击查看 题目大意:在二维平面内有 nnn 个点,表示为 (i,f[i])(i,f[i])(i,f[i]),需要回答 mmm 次询问,每次询问会给出一个矩形,问矩形内有多少个不同的 yyy ...

  8. HDU多校3 - 6975 Forgiving Matching(多项式匹配字符串)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt.规定 kkk 匹配的意思是,两个长度相同的字符串至多有 kkk 个位置是不同的,特别的, ...

  9. HDU多校1 - 6955 Xor sum(字典树+贪心)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,要求找到一段长度最短的区间,使得异或和大于等于 kkk,如果有多种答案,输出左端点最小的那个 题目分析:倒着维护一下后缀异或和,将后缀异或 ...

最新文章

  1. Appro DM8127 IPNC 挂载NFS遇到的问题及解决
  2. 【iCore4 双核心板_FPGA】例程七:状态机实验——状态机使用
  3. PCL:关于pcd数据显示乱码
  4. MySQL INT、TINYINT、SMALLINT、MEDIUMINT、BIGINT(整数类型)
  5. MySQL存储引擎、MyISAM、InnoDB
  6. c++ primer 第六版 pdf_A3N630 塑壳断路器如何更换.pdf
  7. HDU3787 A+B【进制】
  8. 计算机作曲常用软件,计算机作曲——软件与音源的选择
  9. app图标圆角角度_?APP图标造型分析!
  10. Redis(三) Redis的持久化 RDB与AOF
  11. Flutter Sliver滚动组件
  12. 虚拟机Ubuntu中编写C语言程序
  13. 4.2 人工智能产业岗位分布
  14. unity 和安卓互相交互
  15. 交换机分布缓存_述说数据中心交换机的重要性能指标——缓存
  16. 计算机视觉传达论文库,计算机图形视觉传达论文
  17. origin画误差阴影
  18. A2F-轻量级SISR网络 | Lightweight Single-Image Super-Resolution Network with Attentive Auxiliary Feature
  19. 帝国php调用文章列表,帝国CMS模板中:使用php调用最新文章的代码(非灵动和万能标签)...
  20. 稳压二极管稳压电路如何设计

热门文章

  1. mysql导出bacpac_数据库的迁移
  2. MyBatis 插件原理与自定义插件-PageHelper 原理
  3. MyBatis 源码解读-environmentsElement()
  4. 对HTTP/2 支持
  5. Apollo快速使用
  6. SpringBoot高级-消息-AmqpAdmin管理组件的使用
  7. 构造函数和实例对象之间的关系 构造函数创建对象带来的问题 原型
  8. java imap 标记已读,JavaMail通过IMAP和POP3接收未读以及设置已读邮件
  9. skywalking环境搭建
  10. html追加datatype,jquery ajax中dataType的设置问题