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

之前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. 解决C++ builder 4.0编译后的程序在某些计算机上运行出现"EAccessViolation" 的错误

    1. bordbk41.dll is missing or not registered. regsvr32 "C:\Program Files (x86)\Common Files\Bor ...

  2. CSS作业问题 内容回顾

    CSS作业问题 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  3. 前端小知识--区分get和post请求

    get和post是HTTP协议中的两种发送请求的方法. 如果你还不了解http,可以点击[HTTP协议①介绍](https://www.jianshu.com/p/632b890b75ac)[HTTP ...

  4. java的dao层如何返回多个list

    比如一个场景 我要这样展示(相同的元素只要展示一次) 前台是这样写的 el表达式是不能对数据进行处理的,所以数据有重复的那么就一定会显示出来 所以,考虑,能不能直接在dao中查询的时候直接返回三个li ...

  5. 超高频率问题之信息: Illegal access: this web application instance has been stopped already. Could not load . The eventual following stack trace is caused by an error thrown for debugging purposes as well as

    出现频率非常高,目前还不确定具体是什么原因导致

  6. jnhs[未解决]无法使用选定的hibernate配置文件建立数据库连接.请验证hibernate.cfg.xml中的数据库连接详情信息

    工程可以正常的使用读写数据库,当然model和model.hbm.xml文件是自己写的. 解决中

  7. oracle-PL/SQL1

    PL/SQL程序设计 一 PL/SQL简介 到目前为止,在数据库上一直使用单一的SQL语句进行数据操作,没有流程控制,无法开发复杂的应用.Sql是结构化语言; Oracle PL/SQL语言(Proc ...

  8. SQL SERVER 自增列的方法

    declare @Table_name varchar(60) set @Table_name = ''; if Exists(Select top 1 1 from sysobjects       ...

  9. JDBC入门案例

    什么是JDBC? JDBC的全称是Java数据库连接(Java Database Connectivity),它是一套用于执行SQL语句的Java API. 作为一个Web开发人员来说,JDBC操作是 ...

  10. 开发者必看!探秘阿里云Hi购季开发者分会场:海量学习资源0元起!

    摘要: 开发者分会场致力于帮助开发者学习了解阿里云最新技术,为开发者设计全方位的技术成长与进阶之路. 2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: ...