[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. python_opencv库的学习

    一.以灰度图的形式加载彩色图像. https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/py_image_ ...

  2. BZOJ 2019 [Usaco2009 Nov]找工作:spfa【最长路】【判正环】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2019 题意: 奶牛们没钱了,正在找工作.农夫约翰知道后,希望奶牛们四处转转,碰碰运气. 而 ...

  3. 英语影视台词---无敌破坏王2大脑互联网(3)((Ralph)我们去喝根汁汽水吧)

    英语影视台词---无敌破坏王2大脑互联网(3)((Ralph)我们去喝根汁汽水吧) 一.总结 一句话总结: Let's go get a root beer. 1.(Ralph)让我来瞧瞧你的本事  ...

  4. Zookeeper用来干什么?

    在Zookeeper的官网上有这么一句话:ZooKeeper is a centralized service for maintaining configuration information, n ...

  5. 集训Day10

    果然颓的不像话 bzoj3680 gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天 ...

  6. 【Lintcode】075.Find Peak Element

    题目: There is an integer array which has the following features: The numbers in adjacent positions ar ...

  7. 使用django-extension扩展django的manage――runscript命令

    摘要:1.下载安装   1)$easy_installdjango-extensions   2)在INSTALLED_APP中添加'django_extensions'[python]INSTALL ...

  8. javacv实现实时视频截图和录像服务easyCV

    本项目维护于github:https://github.com/eguid/easyCV 1.介绍 本项目基于javaCV1.4.x. 其中实现了 (1)实时视频截图服务(支持rtsp/rtmp/ht ...

  9. Floyd(稠密图,记录路径)

    #include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #i ...

  10. python快速上手教程

    python版本 python目前的版本分为2.7和3.5,两种版本的代码目前无法兼容,查看python版本号: python --version 基本数据类型 数字类型 整型和浮点型数据和其它编程语 ...