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 ...
随机推荐
- 核心API
1.ProcessEngine ProcessEngine是Activiti中最核心的类,其他的类都是由他而来.Activiti流程引擎的配置文件是名为 activiti.cfg.xml 的XML文件 ...
- Android recyclerview删除item刷新列表
删除item坑 mModels.remove(i); notifyItemRemoved(i); //必须调用这行代码 notifyItemRangeChanged(i, mModels.size() ...
- restful知识点之二restframework视图
restful协议理解:面向资源开发 restful协议 ---- 一切皆是资源,操作只是请求方式 ----book表增删改查 /books/ books /books/add/ addbook /b ...
- golang rest api example
package main import ( "net/http" "github.com/gin-gonic/gin" "github.com/jin ...
- Exchange 2016系统要求
一.支持的共存方案 下表列出了一些支持 Exchange 2016 与 Exchange 早期版本共存的应用场景. Exchange 2016与Exchange Server早期版本共存 Exchan ...
- Redis 4.0+安装及配置
系统环境:CentOS 7.3 官方下载最新版:https://redis.io/download:或直接终端下载解析安装: $ wget http://download.redis.io/relea ...
- easyui学习笔记6—基本的Accordion(手风琴)
手风琴也是web页面中常见的一个控件,常常用在网站后台管理中,这里我们看看easyui中基本的手风琴设置. 1.先看看引用的资源 <meta charset="UTF-8" ...
- VMware workstation 虚拟机安装帮助文档(以windows server 2003为例)
本次安装以Windows server 2003为例: 1.在桌面上双击VMware快捷方式打开,并点击文件>新建虚拟机 2.这里选择默认的“典型”,点击下一步 3.选择浏览,找到windows ...
- jsp和servlet的问题收集.... 答案有部分是自己理解的,可能有点差异
如何创建一个动态工程? File ----> New ---->other ---->Web ---->Dynamic Web Project 选择动态WEB 项目工程 W ...
- 百度地图Label 样式 setStyle
最近一直在整百度地图,发现一个小问题: 创建文本标注对象设置样式的时候,其中的backgroundColor属性居然还支持透明啊,不过改变数值好像对效果没有影响 var numLabel = new ...