[LOJ 2039] 「SHOI2015」激光发生器

链接

链接

题解

分为两个部分

第一个是求直线之间的交点找到第一个触碰到的镜面

第二个是求直线经过镜面反射之后的出射光线

第一个很好做,第二个就是将入射光线旋转,注意旋转后在哪一面(可能到镜面背后去)

代码

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} const int maxn = 110;
const double eps = 1e-8;
const double pi = acos(-1); struct Point {
double x, y;
Point(double _x = 0, double _y = 0) {
x = _x; y = _y;
}
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 &b) const {
return (Point){x * b, y * b};
}
};
typedef Point Vector;
struct Line {
Point x; Vector y;
Line() {}
Line(Point _x, Vector _y) {
x = _x; y = _y;
}
};
struct LLL {
Point p1, p2;
double a, b;
} A[maxn];
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 Len(const Vector &a) {
return sqrt(Dot(a, a));
}
int dcmp(double x) {
return fabs(x) < eps ? 0 : (x > 0 ? 1 : -1);
}
Point intersect(const Line &a, const Line &b) {
Vector v = a.x - b.x;
double t = Cross(b.y, v) / Cross(a.y, b.y);
return a.x + a.y * t;
}
double Angle(const Vector &a, const Vector &b) {
return acos(Dot(a, b) / Len(a) / Len(b));
}
bool onseg(const Point &p, const Point &a, const Point &b) {
return dcmp(Dot(a - p, b - p)) <= 0 && dcmp(Cross(a - p, a - p)) == 0;
}
Vector rotate(const Vector &a, double b) {
return (Vector){a.x * cos(b) - a.y * sin(b), a.y * cos(b) + a.x * sin(b)};
}
double X, Y, dx, dy;
int n; void work() {
X = read(), Y = read(), dx = read(), dy = read();
n = read();
rep(i, 1, n) {
A[i].p1.x = read(); A[i].p1.y = read();
A[i].p2.x = read(); A[i].p2.y = read();
A[i].a = read(), A[i].b = read();
}
Point nw = (Point){X, Y};
Vector v = (Vector){dx, dy};
rep(_, 1, 10) {
int ind = 0; double nwdis = 1e9;
rep(i, 1, n) {
if (dcmp(Cross(A[i].p1 - A[i].p2, v)) == 0) continue;
Point p = intersect(Line(A[i].p1, A[i].p2 - A[i].p1), Line(nw, v));
if (onseg(p, A[i].p1, A[i].p2) && dcmp(Dot(v, p - nw)) > 0) {
double dis = Len(p - nw);
if (dis < nwdis) nwdis = dis, ind = i;
}
}
if (!ind) {
if (_ == 1) puts("NONE");
break;
}
printf("%d ", ind);
nw = intersect(Line(A[ind].p1, A[ind].p2 - A[ind].p1), Line(nw, v));
if (dcmp(Dot(A[ind].p1 - A[ind].p2, v)) == 0) v = v * (-1);
else {
Vector nwv;
if (dcmp(Dot(A[ind].p1 - A[ind].p2, v)) > 0) nwv = A[ind].p1 - A[ind].p2;
else nwv = A[ind].p2 - A[ind].p1;
double alpha = pi / 2 - Angle(nwv, v);
if (dcmp(Cross(nwv, v)) > 0) v = rotate(nwv, alpha * A[ind].a / A[ind].b - pi / 2);
else v = rotate(nwv, pi / 2 - alpha * A[ind].a / A[ind].b);
}
}
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

[LOJ 2039] 「SHOI2015」激光发生器的更多相关文章

  1. LOJ#2039. 「SHOI2015」激光发生器(计算几何)

    题面 传送门 题解 如果我初中科学老师知道我有一天计算的时候入射角不等于反射角不知道会不会把我抓起来打一顿-- 这题本质上就是个模拟,需要的芝士也就计蒜几盒的那点,不过注意细节很多,放到考场上只能看看 ...

  2. 【LOJ】#2039. 「SHOI2015」激光发生器

    题解 我永远都写不对计算几何-- 首先找到反射的线段比较好找,扫一遍所有线段然后找交点在镜子上并且交点离起点最近的那条线段 然后旋转的时候,有可能是顺时针,也有可能是逆时针,要找出法线,然后判断法线和 ...

  3. loj#2038. 「SHOI2015」超能粒子炮・改

    题目链接 loj#2038. 「SHOI2015」超能粒子炮・改 题解 卢卡斯定理 之后对于%p分类 剩下的是个子问题递归 n,k小于p的S可以预处理,C可以卢卡斯算 代码 #include<c ...

  4. loj #2037. 「SHOI2015」脑洞治疗仪

    #2037. 「SHOI2015」脑洞治疗仪   题目描述 曾经发明了自动刷题机的发明家 SHTSC 又公开了他的新发明:脑洞治疗仪——一种可以治疗他因为发明而日益增大的脑洞的神秘装置. 为了简单起见 ...

  5. Loj #2036. 「SHOI2015」自动刷题机

    link : https://loj.ac/problem/2036 这个显然具有单调性,N小的话更容易A题,不仅因为A一次题减少的代码,并且A题的下限也低. 所以直接上二分就行了,注意上限一定不要设 ...

  6. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  7. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  8. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  9. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

随机推荐

  1. Ubuntu 更新/安装nodejs

    nvm nvm是一个开源的Node版本管理器,通过简单的bash脚本来管理.切换多个Node.js版本.和nvm提供类似功能的还有tj写的n,它们的功能大同小异,整体来说nvm要稍强大一下.值得注意的 ...

  2. 分享知识-快乐自己:SpringMvc中 页面日期格式到后台的类型转换

    日期格式的类型转换: 以往在 from 表单提交的时候,都会有字符串.数字.还有时间格式等信息. 往往如果是数字提交的话底层会自动帮我们把类型进行了隐式转换. 但是日期格式的却不能自动转换,这就需要我 ...

  3. Luke 5—— 可视化 Lucene 索引查看工具,可以查看ES的索引

    Luke 5 发布,可视化 Lucene 索引查看工具  oschina 发布于2015年08月31日  这是一个主要版本,该版本支持 Lucene 5.2.0. 它支持 elasticsearch ...

  4. 无言以队Alpha阶段项目复审

    小组的名字和链接 优点 缺点,bug报告 (至少140字) 最终名次 (无并列) 甜美女孩 http://www.cnblogs.com/serendipity-zeng/p/9937832.html ...

  5. PHP中调用接口

    引用:http://zhidao.baidu.com/question/454935450.html&__bd_tkn__=67bd5d3a742a8b244e09a86fb8b824aa95 ...

  6. listen 68 Theoretical Physicist Stephen Hawking Dies at 76

    World-renowned British physicist Stephen Hawking, who sought to understand a range of cosmic topics ...

  7. Linux下的磁盘缓存

    转自:http://blog.csdn.net/cywosp/article/details/21126161 前段时间在开发一个使用SSD做缓存的系统,在高速写入数据时会出现大量的磁盘缓存.太多的磁 ...

  8. 每天一个linux命令(1):man命令

    版权声明 更新:2017-04-19博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下命令man. 2 ...

  9. Mycat概述

    Mycat是什么?从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的的Server,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用 ...

  10. BZOJ1503:[NOI2004]郁闷的出纳员

    浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...