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

之前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. H5C3--盒子模型

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 基于jquery实现图片上传本地预览功能

    一.原理 分为两步: 当上传图片的input被触发并选择本地图片之后获取要上传的图片这个对象的URL(对象URL),把对象URL赋值给事先写好的img标签的src属性即可把图片显示出来.在这里,我们需 ...

  3. DLX

    #include <iostream> #include <cstdlib> #include <cstring> #include <queue> # ...

  4. Windows下Git的下载、安装、设置用户名和邮箱、创建版本库等

    Git官网:https://git-scm.com/ 一.Git下载 官网首页下载,当前最新版本:2.24.1 本人下载的是Git for Windows版本:Git-2.24.1.2-64-bit. ...

  5. 提升mysql服务器性能(索引与查询优化)

    原文:提升mysql服务器性能(索引与查询优化) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/details/90138407 ...

  6. Django静态文件以及模板文件的配置 jQuery v1.12.4

    1.配置模板的路径 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os. ...

  7. 基于遗传算法(Genetic Algorithm)的TSP问题求解(C)

    基于遗传算法的TSP问题求解(C) TSP问题: TSP(Travelling salesman problem): 译作“旅行商问题”, 一个商人由于业务的需要,要到n个城市,每个城市之间都有一条路 ...

  8. 产生冠军 HDU - 2094 (拓扑排序)

    分析: 当有且只有一个节点入度为0时,该节点即为冠军,否则不能产生冠军.所以以下代码中只要入度大于0的无论是几都将其设置为1. #include <stdio.h> #include &l ...

  9. 订阅 如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件

    如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件 标签: idea git 插件 分类: Git 最近初学Git,而且在使用的IDE是IntelliJ IDEA,发现IDE ...

  10. 50倍时空算力提升,阿里云RDS PostgreSQL GPU版本上线

    2019年3月19日,阿里云RDS PostgreSQL数据库GPU规格版本正式上线,开启了RDS异构计算并行加速之路.该版本在RDS(关系型数据库服务)的云基础设施层面首次完成了与阿里云异构计算产品 ...