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. 用iframe踩的坑

    1.无法监控iframe加载成功与否 经测试,火狐及chorme都不支持onerror事件,而且,不管iframe加载是否成功,都会触发onload事件. 1)通过postmessage消息提示是否加 ...

  2. 54个提高PHP程序运行效率的方法(转载)

    原文地址:http://www.jb51.net/article/69677.htm 1. 如果一个方法可静态化,就对它做静态声明.速率可提升至4倍. 2. echo 比 print 快. 3. 使用 ...

  3. postgres备份数据库

    1. psql --help psql is the PostgreSQL interactive terminal. Usage: psql [OPTION]... [DBNAME [USERNAM ...

  4. 【Python】Python3基本语法入门学习

    0.Python概述 1.First Word Game 2.变量与字符串 3.improved game 4.Python数据类型 5.常用操作符 6.分支与循环 7.列表 8.元组 9.字符串内置 ...

  5. Winform访问本地SQLServer数据库文件

    Winform访问本地SQLServer数据库文件 1.项目中添加config配置,如下: <configuration> <connectionStrings> <ad ...

  6. Java基础之异常处理机制

    在Java中,异常分为编译时异常和运行时异常. 编译时异常又叫编译时被监测的异常:在程序编译过程中监测到非运行时异常的异常,出现该异常要么向上抛出,要么捕获处理.运行时异常(runtimeExcept ...

  7. androidcookie

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { webSettings.setAllowFileAccessFrom ...

  8. July 17th 2017 Week 29th Monday

    A heart is a heavy burden. 心,可是很重的. Follow your heart, but always take your brain with you. Easy to ...

  9. 转化ico标志

    emmm,谨此纪念我这七秒钟的记忆. ico最简单的转化方法,上网搜索ico图标转换即可

  10. 六种排序算法的JavaScript实现以及总结

    最近几天在系统的复习排序算法,之前都没有系统性的学习过,也没有留下过什么笔记,所以很快就忘了,这次好好地学习一下. 首先说明为了减少限制,以下代码通通运行于Node V8引擎而非浏览器,源码在我的Gi ...