计算几何的题做的真是少之又少。

之前wa以为是精度问题,后来发现是情况没有考虑全。。。


题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5572

题意:

给定起点A和方向V,路径中遇到圆柱体会发生折射,问能否到达终点B。

分析:

将路径表示为a+t∗v得到关于t的二元方程组,求出Δ。

Δ小于等于0时,表示不会发生折射。直接判断ab是否共线。

Δ大于0时,求出根。

  1. 根小于0说明路上不会发生折射,判断ab是否共线。
  2. 根大于等于0,仍然要判断ab是否共线,并注意此时b应该a与交点的线段上。如果b未在线段上,则判断折射后能否经过b。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const double eps= 1e-8;
const double INF = 1e20;
double add(double a, double b)
{
if(fabs(a + b) < eps * (fabs(a) + fabs(b))) return 0;
else return a + b;
}
struct Point{
double x, y;
Point(){}
Point(double x, double y):x(x), y(y){}
Point operator + (Point p){
return Point(add(x, p.x), add(y, p.y));
}
Point operator - (Point p){
return Point(add(x, -p.x), add(y, -p.y));
}
double dot(Point p){
return add(x * p.y, - y * p.x);
}
Point operator * (double d){
return Point(x * d, y * d);
}
};
struct Circle{
Point o;
double r;
Circle(){}
Circle(double x, double y, double r):o(x, y), r(r){}
};
Point a, b, v;
Circle c;
inline int dcmp(double a){if(fabs(a) < eps) return 0; return a < 0 ? -1:1;}
inline bool online(Point a, Point v, Point b){return dcmp(v.dot(b-a)) == 0;}
inline double getpos(Point a, Point b)
{
if(dcmp(a.x) == 0) return b.y / a.y;
else return b.x / a.x;
}
bool judge(Point a, Point v, Circle c, Point b)
{
double aa = v.x * v.x + v.y * v.y;
double bb = 2 * v.y * (a.y - c.o.y) + 2 * v.x * (a.x - c.o.x);
double cc = (a.x - c.o.x) * (a.x - c.o.x) + (a.y - c.o.y) * (a.y - c.o.y) - c.r * c.r;
double delta = bb * bb - 4 * aa * cc;
double t1, t2, t;
if(dcmp(delta) <= 0){
if(online(a, v, b)){
t = getpos(v, b - a);
if(dcmp(t) >= 0) return true;
}
}
double anst = INF;
t1 = (- bb + sqrt(delta))/(2 * aa);
t2 = (- bb - sqrt(delta))/(2 * aa);
if(dcmp(t1) >= 0){
if(dcmp(t2) >= 0) anst = t2;
else anst = t1;
if(online(a, v, b)){
double t = getpos(v, b - a);
if(dcmp(t) >= 0 && t <= anst) return true;
}
Point tmp = a + v * anst;
Point temp = c.o - tmp;
Point revers = Point(-temp.y, temp.x);
double k = temp.dot(tmp - b) / revers.dot(temp);
Point tt = tmp + revers * k;
b = tt * 2 - b;
if(online(a, v, b)){
double tmp = getpos(v, b - a);
if(dcmp(tmp) >= 0) return true;
}
}
if(online(a, v, b)){
double t = getpos(v, b - a);
if(dcmp(t) >= 0) return true;
}
return false;
}
int main (void)
{
int T;cin>>T;
int cnt = 1;
while(T--){
double QX, QY, R;
cin>>QX>>QY>>R;
c = Circle(QX, QY, R);
double AX, AY, VX, VY, BX, BY;
cin>>AX>>AY>>VX>>VY>>BX>>BY;
a = Point(AX, AY);
v = Point(VX, VY);
b = Point(BX, BY);
cout<<"Case #"<<cnt<<": ";
if(judge(a, v, c, b)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
cnt++;
}
return 0;
}

HDU 5572 An Easy Physics Problem【计算几何】的更多相关文章

  1. HDU 5572 An Easy Physics Problem (计算几何+对称点模板)

    HDU 5572 An Easy Physics Problem (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5572 Descripti ...

  2. hdu 5572 An Easy Physics Problem 圆+直线

    An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  3. HDU - 5572 An Easy Physics Problem (计算几何模板)

    [题目概述] On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volum ...

  4. 【HDU 5572 An Easy Physics Problem】计算几何基础

    2015上海区域赛现场赛第5题. 题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5572 题意:在平面上,已知圆(O, R),点B.A(均在圆外),向量 ...

  5. 2015 ACM-ICPC 亚洲区上海站 A - An Easy Physics Problem (计算几何)

    题目链接:HDU 5572 Problem Description On an infinite smooth table, there's a big round fixed cylinder an ...

  6. HDU 5572--An Easy Physics Problem(射线和圆的交点)

    An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  7. ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

    题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...

  8. HDU 4974 A simple water problem(贪心)

    HDU 4974 A simple water problem pid=4974" target="_blank" style="">题目链接 ...

  9. hdu 1040 As Easy As A+B

    As Easy As A+B Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

随机推荐

  1. nginx链接末尾自动补全斜杠

    放在locaation里边就行 if (-d $request_filename){ rewrite ^(.*[^/])$ $/ permanent;#加斜杠 } 这样,nginx就会进行判断了,如果 ...

  2. 解决前端跨域请求(SpringBoot)

    @Configuration public class CorsConfig { private CorsConfiguration buildConfig() { CorsConfiguration ...

  3. Vue表单验证插件的制作过程

    一.表单验证模块的构成 任何表单验证模块都是由 配置――校验――报错――取值 这几部分构成的. 配置: 配置规则 和配置报错,以及优先级 校验: 有在 change 事件校验, 在点击提交按钮的时候校 ...

  4. 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储。

    https://github.com/kcloze/swoole-jobs 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储.参考资料:swoole https:/ ...

  5. Js Array 删除

    数组删除操作 Array.prototype.inArray = function (e) {for (i = 0; i < this.length; i++) {if (this[i] == ...

  6. LUOGU P1512 伊甸园日历游戏

    题目描述 Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来.然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到 ...

  7. svn利用钩子脚本功能实现代码同步到web目录

    一.hook简单介绍 为了方便管理员控制提交的过程 ,Subversion提供了hook机制.当特定的 事件发生时,相应的 hook会被调用,hook其实就相当于特定事件的处理函数.每个hook会得到 ...

  8. Springboot 创建的maven获取resource资源下的文件的两种方式

    Springboot 创建的maven项目 打包后获取resource下的资源文件的两种方式: 资源目录: resources/config/wordFileXml/wordFileRecord.xm ...

  9. linux系统命令配置文件

    系统命令要独占地控制系统,并让一切正常工作.所有如 login(完成控制台用户身份验证阶段)或 bash(提供用户和计算机之间交互)之类的程序都是系统命令.因此,和它们有关的文件也特别重要.这一类别中 ...

  10. Leetcode693.Binary Number with Alternating Bits交替位二进制数

    给定一个正整数,检查他是否为交替位二进制数:换句话说,就是他的二进制数相邻的两个位数永不相等. 示例 1: 输入: 5 输出: True 解释: 5的二进制数是: 101 示例 2: 输入: 7 输出 ...