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

Problem Description
On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volume can be ignored.

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.

Input
First line contains an integer T, which indicates the number of test cases.

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).

⋅ 1 ≤ T ≤ 100.

⋅ |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.

 
 
Output
For every test case, you should output "Case #x: y", where x indicates the case number and counts from 1. y is "Yes" if the ball will pass point B after some time, otherwise y is "No".
 
Sample Input
2 0 0 1 2 2 0 1 -1 -1 0 0 1 -1 2 1 -1 1 2
 
Sample Output
Case #1: No Case #2: Yes
 
先判断射线和圆交点个数,如果小于2再看是否B在A的前进方向上,没有则NO,否则YES。如果等于2,就先找到第一个交点,将这个交点和圆心连成直线,那么A的路径关于这条直线对称,那么如果A关于此直线的对称点在圆心->B路径上,则可以相撞,否则不行。
这里有一个小问题,如果反过来求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(射线和圆的交点)的更多相关文章

  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. HDU 5572 An Easy Physics Problem【计算几何】

    计算几何的题做的真是少之又少. 之前wa以为是精度问题,后来发现是情况没有考虑全... 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5572 题意: ...

  6. 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 ...

  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. [小北De编程手记] : Lesson 04 - Selenium For C# 之 API 上

    这一部分,我准备向大家介绍Selenium WebDriver的常用API,学习这部分内容需要大家最好有一些简单的HTML相关知识,本文主要涉及到以下内容: Selenium API:元素检查 Sel ...

  2. Windows操作系统下给文件夹右键命令菜单添加启动命令行的选项

    在命令行中或按下[WIN]+[R]键启动运行对话框的情况下,输入regedit命令启动注册表编辑器,在HKEY_CLASSES_ROOT\Folder\shell下增加一个“CMD”(此处名字可以随便 ...

  3. Maven 安装与使用(一)

    1. 安装 参考:http://maven.apache.org/install.html A. win7环境下,官网下载maven安装文件 B. 解压缩maven文件 C. 确认已配置好JAVA环境 ...

  4. VS2015配置Entity Framework Power Tools Bate4,还有一些使用与注意的地方

    今天使用vs2015重新安装了这个名为Entity Framework Power Tools的插件,由于它只支持到2013,因此需要进行一些操作方能使用 下面是一些参考文档 http://www.c ...

  5. docker commit 显示“invalid reference format”

    docker commit的时候一直显示invalid reference format,改了几次也不行,后来发现是因为docker镜像的名字中不能包含大写字母,改成小写后就行了

  6. List 的 removeAll 方法的效率

    List 的 removeAll 方法的效率低的原因: 要遍历source,对dest进行contain操作,而contain又要遍历dest进行equal比较. 解决办法:dest转为set,用se ...

  7. OC基础数据类型-NSNumber

    1.NSNumber:专门用来装基础类型的对象,把整型.单精度.双精度.字符型等基础类型存储为对象 //基本数据类型 //专门用来装基础类型的对象 NSNumber * intNumber = [[N ...

  8. jq实现随机显示部分图片在页面上(兼容IE5)

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

  9. Codeforces Round #433 (Div. 2)【A、B、C、D题】

    题目链接:Codeforces Round #433 (Div. 2) codeforces 854 A. Fraction[水] 题意:已知分子与分母的和,求分子小于分母的 最大的最简分数. #in ...

  10. SpringMVC 如何定义类型转换器

    举例说明, 将一个字符串转换成的 User 类型. 例如将字符串 1-zcd-1234-zcd@163.com-1999/12/12  转换成User 类型. 一.实体类 public class U ...