HDU 5572--An Easy Physics Problem(射线和圆的交点)
An Easy Physics Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3845 Accepted Submission(s): 768
Currently the ball stands still at point A, then we'll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.
We're just curious about whether the ball will pass point B after some time.
Every test case contains three lines.
The first line contains three integers Ox, Oy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.
The second line contains four integers Ax, Ay, Vx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).
The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).
⋅ |Ox|,|Oy|≤ 1000.
⋅ 1 ≤ r ≤ 100.
⋅ |Ax|,|Ay|,|Bx|,|By|≤ 1000.
⋅ |Vx|,|Vy|≤ 1000.
⋅ Vx≠0 or Vy≠0.
⋅ both A and B are outside of the cylinder and they are not at same position.
这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.
#include <iostream>
#include <cstdio>
#include <cstring>
#include<algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const double eps = 1e-;
int sgn(double x) {
if (fabs(x) < eps)return ;
if (x < )return -;
else return ;
}
struct point {
double x, y;
point() {}
point(double x, double y) : x(x), y(y) {}
void input() {
scanf("%lf%lf", &x, &y);
}
bool operator ==(point b)const {
return sgn(x - b.x) == && sgn(y - b.y) == ;
}
bool operator <(point b)const {
return sgn(x - b.x) == ? sgn(y - b.y)< : x<b.x;
}
point operator -(const point &b)const { //返回减去后的新点
return point(x - b.x, y - b.y);
}
point operator +(const point &b)const { //返回加上后的新点
return point(x + b.x, y + b.y);
}
point operator *(const double &k)const { //返回相乘后的新点
return point(x * k, y * k);
}
point operator /(const double &k)const { //返回相除后的新点
return point(x / k, y / k);
}
double operator ^(const point &b)const { //叉乘
return x*b.y - y*b.x;
}
double operator *(const point &b)const { //点乘
return x*b.x + y*b.y;
}
double len() { //返回长度
return hypot(x, y);
}
double len2() { //返回长度的平方
return x*x + y*y;
}
point trunc(double r) {
double l = len();
if (!sgn(l))return *this;
r /= l;
return point(x*r, y*r);
}
};
struct line {
point s;
point e;
line() { }
line(point _s, point _e) {
s = _s;
e = _e;
}
bool operator ==(line v) {
return (s == v.s) && (e == v.e);
}
//返回点p在直线上的投影
point lineprog(point p) {
return s + (((e - s)*((e - s)*(p - s))) / ((e - s).len2()));
}
//返回点p关于直线的对称点
point symmetrypoint(point p) {
point q = lineprog(p);
return point( * q.x - p.x, * q.y - p.y);
}
//点是否在线段上
bool pointonseg(point p) {
return sgn((p - s) ^ (e - s)) == && sgn((p - s)*(p - e)) <= ;
}
};
struct circle {//圆
double r; //半径
point p; //圆心
void input() {
p.input();
scanf("%lf", &r);
}
circle() { }
circle(point _p, double _r) {
p = _p;
r = _r;
}
circle(double x, double y, double _r) {
p = point(x, y);
r = _r;
}
//求直线和圆的交点,返回交点个数
int pointcrossline(line l, point &r1, point &r2) {
double dx = l.e.x - l.s.x, dy = l.e.y - l.s.y;
double A = dx*dx + dy*dy;
double B = * dx * (l.s.x - p.x) + * dy * (l.s.y - p.y);
double C = (l.s.x - p.x)*(l.s.x - p.x) + (l.s.y - p.y)*(l.s.y - p.y) - r*r;
double del = B*B - * A * C;
if (sgn(del) < ) return ;
int cnt = ;
double t1 = (-B - sqrt(del)) / ( * A);
double t2 = (-B + sqrt(del)) / ( * A);
if (sgn(t1) >= ) {
r1 = point(l.s.x + t1 * dx, l.s.y + t1 * dy);
cnt++;
}
if (sgn(t2) >= ) {
r2 = point(l.s.x + t2 * dx, l.s.y + t2 * dy);
cnt++;
}
return cnt;
}
};
point A, V, B;
circle tc;
point r1, r2;
int main() {
int t, d = ;
scanf("%d", &t);
while (t--) {
tc.input();
A.input();
V.input();
B.input();
int f = ;
int num = tc.pointcrossline(line(A, A + V), r1, r2);
if (num < ) {
point t = B - A;
if (t.trunc() == V.trunc()) f = ;
else f = ;
}
else {
line l = line(tc.p, r1);
line l1 = line(A, r1);
line l2 = line(r1, B);
point t = l.symmetrypoint(A);
if (l1.pointonseg(B))f = ;
else if (l2.pointonseg(t))f = ; //求B的对称点会WA
else f = ;
}
if (f == )
printf("Case #%d: Yes\n", d++);
else
printf("Case #%d: No\n", d++);
}
return ;
}
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(均在圆外),向量 ...
- HDU 5572 An Easy Physics Problem【计算几何】
计算几何的题做的真是少之又少. 之前wa以为是精度问题,后来发现是情况没有考虑全... 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5572 题意: ...
- 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 ...
- 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 ...
随机推荐
- 转动的八卦图纯css实现
这类的东西网上一搜就是大把的,看着比较空旷的博客,所以自己也来写一个. <!DOCTYPE html> <html> <head> <meta chars ...
- vue.js与angular.js的区别(个人)
刚进入实训 讲师就要发一些什么比较高大上的东西,本人才疏学浅 浅浅的分享一下angularjs 和vue.js的区别.只是简单的理解一下 大神勿喷. 生实训之前学习的angular.js 只是理解了 ...
- eclipse svn使用
简单介绍一些基本操作 1.同步在Eclipse下,右击你要同步的工程->team->与资源库同步->这时会进入同步透视图,会显示出本机与SVN上内容有不同的文件,双击文件名,会显示出 ...
- JAVA语法基础要点
- linux 文件常用操作
linux 文件基本操作 新建文件:touch test 不会替换重名文件,并且linux一切都是文件,文件夹和文件不能重名 新建文件夹:mkdir test使用 -p 参数,同时创建父目录(如果不存 ...
- MSSQL 备份与恢复
建立维护计划,需启用<SQL Server 代理>服务 建立三个子作业: 1. 按周进行的全备份,每周日零点执行 2. 按天进行的差异备份,每天中午12点执行 3. 按小时执行的事务日志备 ...
- C# 使用 Invoke 实现函数的白盒 UT 测试
公有方法可以直接调用,但是一些非公开的方法,在覆盖率测试的时候也需要覆盖,可以使用 Invoke 来调用. 调用方法如下,其中 this 可以改为被调用的方法所属的类名,通过 BindingFlags ...
- 云计算之概念——IaaS、SaaS、PaaS、Daas
云计算通俗来说就是输入/输出和计算不在一个主机上.计算要用到计算设备,计算设备一般是指CPU.内存和硬盘,输入/输出设备一般是指键盘.鼠标.显示器.耳机.音响.话筒等外设.而我们的个人计算机是使用主板 ...
- yii2.0里别名的定义
别名用来表示文件路径和URL,为了避免在代码中硬编码一些绝对路径和URL,一个别名必须以‘@’符开头. 用Yii::setAlias()的方法来设置: //文件别名 Yii::setAlias('@f ...
- Linux:CentOS7卸载mysql
步骤 方法一. 1.查看mysql安装 rpm -qa|grep -i mysql 2.卸载前关闭mysql服务 rpm -ev --nodeps mysql-community-release-el ...