poj 1263 Reflections (Simple Geometry)
简单计算几何。题目给出射线以及若干个不相交的圆,求出射线会在哪些圆上反弹,依次写出反弹球的编号。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector> using namespace std; const double EPS = 1e-;
template<class T> T sqr(T x) { return x * x;}
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
bool operator < (Point a) const { return sgn(x - a.x) < || sgn(x - a.x) == && y < a.y;}
bool operator == (Point a) const { return sgn(x - a.x) == && sgn(y - a.y) == ;}
Point operator + (Point a) { return Point(x + a.x, y + a.y);}
Point operator - (Point a) { return Point(x - a.x, y - a.y);}
Point operator * (double p) { return Point(x * p, y * p);}
Point operator / (double p) { return Point(x / p, y / p);}
} ;
typedef Point Vec; inline double cross(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
inline double cross(Point o, Point a, Point b) { return cross(a - o, b - o);}
inline double dot(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
inline double dot(Point o, Point a, Point b) { return dot(a - o, b - o);}
inline double veclen(Vec x) { return sqrt(dot(x, x));}
inline Vec normal(Vec x) { return Vec(-x.y, x.x) / veclen(x);} struct Line {
Point s, t;
Line() {}
Line(Point s, Point t) : s(s), t(t) {}
Vec vec() { return t - s;}
Point pt(double x) { return s + vec() * x;}
Line move(double x) {
Vec nor = normal(vec());
return Line(s + nor * x, t + nor * x);
}
} ; inline Point llint(Point P, Vec v, Point Q, Vec w) { return P + v * (cross(w, P - Q) / cross(v, w));}
inline Point llint(Line a, Line b) { return llint(a.s, a.vec(), b.s, b.vec());} struct Circle {
Point c;
double r;
Circle() {}
Circle(Point c, double r) : c(c), r(r) {}
} ; void lcint(Line L, Circle C, vector<Point> &sol) {
Point ip = llint(L, Line(C.c, C.c + normal(L.vec())));
double dis = veclen(ip - C.c);
if (sgn(dis - C.r) >= ) return ;
Vec u = L.vec() / veclen(L.vec());
double d = sqrt(sqr(C.r) - sqr(dis));
sol.push_back(ip + u * d);
sol.push_back(ip - u * d);
} Point reflect(Point x, Line L) {
Vec nor = normal(L.vec());
Point ip = llint(L, Line(x, x + nor));
return ip + ip - x;
} vector<Circle> rec;
Point src;
Vec dir; const double FINF = 1e100;
inline bool onCircle(Point p, Circle c) { return sgn(veclen(p - c.c) - c.r) == ;} void work() {
int cnt = , sz = rec.size();
vector<Point> tmp;
Point ip;
while (true) {
tmp.clear();
double d = FINF;
for (int i = ; i < sz; i++) lcint(Line(src, src + dir), rec[i], tmp);
for (int i = , sz = tmp.size(); i < sz; i++) {
double t = (tmp[i].x - src.x) / dir.x;
if (t > EPS) d = min(d, t);
}
if (sgn(d - FINF) >= ) break;
cnt++;
if (cnt > ) break;
ip = src + dir * d;
int mk = -;
for (int i = ; i < sz; i++) if (onCircle(ip, rec[i])) { mk = i; break;}
if (mk == -) { puts("shit!!"); while () ;}
printf("%d ", mk + );
dir = reflect(src, Line(ip, rec[mk].c)) - ip;
src = ip;
}
if (cnt > ) puts("...");
else puts("inf");
} int main() {
// freopen("in", "r", stdin);
int cas = , n;
double x, y, r;
while (cin >> n && n) {
rec.clear();
while (n--) {
cin >> x >> y >> r;
rec.push_back(Circle(Point(x, y), r));
}
cin >> src.x >> src.y;
cin >> dir.x >> dir.y;
dir = dir / veclen(dir);
printf("Scene %d\n", cas++);
work();
puts("");
}
return ;
}
速度好慢,整整写了一个小时。对几何模板还是不算非常熟悉,虽然已经能够灵活写出部分基础函数了,但是速度还真是一个大问题。最后结果,因为手多血多个换行PE了一次,然后就AC了~
——written by Lyon
poj 1263 Reflections (Simple Geometry)的更多相关文章
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
		POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ... 
- POJ 3468.A Simple Problem with Integers-线段树(成段增减、区间查询求和)
		POJ 3468.A Simple Problem with Integers 这个题就是成段的增减以及区间查询求和操作. 代码: #include<iostream> #include& ... 
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
		题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ... 
- 线段树(成段更新) POJ 3468 A Simple Problem with Integers
		题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ... 
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
		A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ... 
- poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解
		A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ... 
- POJ 3922	 A simple stone game
		题目: E - A simple stone game Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d &am ... 
- POJ 3468 A Simple Problem with Integers      //线段树的成段更新
		A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 59046 ... 
- [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]
		A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ... 
随机推荐
- Vijos1212  Way Selection   [2017年6月计划 二分图03]
			Way Selection 背景 小杉家族遭遇了前所未有的大危机 他想知道怎么逃生 描述 小杉家族r个人正在一片空地上散步,突然,外星人来了…… 留给小杉家族脱逃的时间只有t秒,每个小杉都有一个跑的速 ... 
- 微信小程序之组件开发中的基础知识
			跟着视频开始小程序的项目的开发,视频中这个小程序已经上线了,可以很好的看着小程序的界面进行开发,昨天看了一下具体的需求,觉得真的细节好多啊,而且其中设计的组件的思想也是很好的,能够很好的实现代码的复用 ... 
- Git clone远程仓库
			git clone git@ip地址:/home/git_data/wechat.git 
- python 类属性、静态方法与类方法
			1. 类属性 1.1 定义 在类中方法外通过属性名 = 属性值定义的属性 访问方式: 类名.属性名 对象名.属性名 class Student: cls_id = 102 stu = Student( ... 
- FreeMarker中<#include>和<#import>标签的区别
			在使用freemarker作为前端页面模板的应用中,会有很多的freemarker模板页面,这些ftl会在不同的页面中重复使用,一是为了简化布局的管理,二是可以重复使用一些代码. 在freemarke ... 
- 【Vue】详解组件的基础与高级用法
			Vue.js 最核心的功能就是组件(Component),从组件的构建.注册到组件间通信,Vue 2.x 提供了更多方式,让我们更灵活地使用组件来实现不同需求. 一.构建组件 1.1 组件基础 一个组 ... 
- 计算机网络 5.6-5.8 TCP/UDP
			来看看传输层的位置 要点: 传输层是为两个应用进程提供端到端的通信 传输层的复用和分用 传输层与应用层就是端口 (传输层的应用访问点 TSP) 传输层与网络层之间就是协议字段(网络层的 NTSP) 端 ... 
- Effective Modern C++:08调整
			41:针对可复制的形参,在移动成本低且一定会被复制的前提下,考虑将其按值传递 class Widget { public: void addName(const std::string& ne ... 
- UCloud-201809-001:Redis服务未授权访问漏洞安全预警
			UCloud-201809-001:Redis服务未授权访问漏洞安全预警 尊敬的UCloud用户,您好! 发布时间 2018-09-11更新时间 2018-09-11漏洞等级 HighCVE编号 ... 
- Polyfill简介
			1.什么是Polyfill? Polyfill是一个js库,主要抚平不同浏览器之间对js实现的差异.比如,html5的storage(session,local), 不同浏览器,不同版本,有些支持,有 ... 
