HDU 5572 An Easy Physics Problem【计算几何】
计算几何的题做的真是少之又少。
之前wa以为是精度问题,后来发现是情况没有考虑全。。。
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5572
题意:
给定起点A和方向V,路径中遇到圆柱体会发生折射,问能否到达终点B。
分析:
将路径表示为a+t∗v得到关于t的二元方程组,求出Δ。
Δ小于等于0时,表示不会发生折射。直接判断ab是否共线。
Δ大于0时,求出根。
- 根小于0说明路上不会发生折射,判断ab是否共线。
- 根大于等于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【计算几何】的更多相关文章
- HDU 5572 An Easy Physics Problem (计算几何+对称点模板)
HDU 5572 An Easy Physics Problem (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5572 Descripti ...
- hdu 5572 An Easy Physics Problem 圆+直线
An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU - 5572 An Easy Physics Problem (计算几何模板)
[题目概述] On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volum ...
- 【HDU 5572 An Easy Physics Problem】计算几何基础
2015上海区域赛现场赛第5题. 题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5572 题意:在平面上,已知圆(O, R),点B.A(均在圆外),向量 ...
- 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 ...
- HDU 5572--An Easy Physics Problem(射线和圆的交点)
An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem
题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...
- HDU 4974 A simple water problem(贪心)
HDU 4974 A simple water problem pid=4974" target="_blank" style="">题目链接 ...
- 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 ...
随机推荐
- 微信小程序之组件的集合(二)
继续微信小程序开发的学习,继续跟着老师的讲课思路来学习,继续开发项目中所用到的组件 一.导航栏navi组件的开发 1.新建组件的文件结构 这个就是先新建目录navi.然后在navi文件夹中新建comp ...
- bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 看Zinn博客水过去…… 运用拟阵可以证明按价格从小到大买的贪心是正确的.但自己还不会 ...
- bzoj 4241 历史研究——分块(区间加权众数)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4241 套路:可以大力预处理,如果求区间加权众数,可以预处理i~j块(或 j 位置)的最大值, ...
- xml转化为数组
function xml_to_array($xml) { return json_decode(json_encode(simplexml_load_string($xml)), true); }
- nginx的四个基本功能
Nginx能做什么 1.反向代理2.负载均衡3.HTTP服务器(包含动静分离)4.正向代理 以上就是做网站小编了解到的Nginx在不依赖第三方模块能处理的事情,下面详细说明每种功能怎么做 1.反向代理 ...
- Spring事务_注解_特性
Spring 是一个 IOC 和 AOP 容器框架. ## 控制反转(IOC) ## 传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间 ...
- Socket与TcpClient的区别
原文:Socket与TcpClient的区别 Socket和TcpClient有什么区别 原文:http://wxwinter.spaces.live.com/blog/cns!C36588978AF ...
- 洛谷P1368 均分纸牌(加强版) [2017年6月计划 数论14]
P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取 ...
- line-height的用法(一)
行高”顾名思意指一行文字的高度.具体来说是指两行文字间基线之间的距离. 从上到下四条线分别是顶线.中线.基线.底线,很像才学英语字母时的四线三格,我们知道vertical-align属性中有top.m ...
- SDUT-3377_数据结构实验之查找五:平方之哈希表
数据结构实验之查找五:平方之哈希表 Time Limit: 400 ms Memory Limit: 65536 KiB Problem Description 给定的一组无重复数据的正整数,根据给定 ...