HDU 5572 (平面几何)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

题目链接:点击这里

题意: 平面上一个圆, 两个圆外的点A,B, 给A一个初速度, 问能否碰到B.

根据 A 的运行射线轨迹分成两种情况:
1. 如果运行时不撞到圆, 那么判断B在射线上即可;
2. 如果撞到圆, 求出比较近的那个交点 P , 求出A关于 OP 的对称点 A , 那么判断 B 在线段AP或者射线 PA 上即可.

trick:因为输入都是整数, 所以精度开的大一点.

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define maxn 100005

const double eps = 1e-5;
const double INF = 1e20;
const double pi = acos (-1.0);

int dcmp (double x) {
    if (fabs (x) < eps) return 0;
    return (x < 0 ? -1 : 1);
}
inline double sqr (double x) {return x*x;}

//*************点
struct Point {
    double x, y;
    Point (double _x = 0, double _y = 0):x(_x), y(_y) {}
    void input () {scanf ("%lf%lf", &x, &y);}
    void output () {printf ("%.2f %.2f\n", x, y);}
    bool operator == (const Point &b) const {
        return (dcmp (x-b.x) == 0 && dcmp (y-b.y) == 0);
    }
    bool operator < (const Point &b) const {
        return (dcmp (x-b.x) == 0 ? dcmp (y-b.y) < 0 : 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 * (double a) {
        return Point (x*a, y*a);
    }
    Point operator / (double a) {
        return Point (x/a, y/a);
    }
    double len2 () {//返回长度的平方
        return sqr (x) + sqr (y);
    }
    double len () {//返回长度
        return sqrt (len2 ());
    }
    Point change_len (double r) {//转化为长度为r的向量
        double l = len ();
        if (dcmp (l) == 0) return *this;//零向量返回自身
        r /= l;
        return Point (x*r, y*r);
    }
};

double cross (Point a, Point b) {//叉积

    return a.x*b.y-a.y*b.x;
}
double dot (Point a, Point b) {//点积

    return a.x*b.x + a.y*b.y;
}
double dis (Point a, Point b) {//两个点的距离

    Point p = b-a; return p.len ();
}

//************直线 线段
struct Line {
    Point s, e;//直线的两个点
    double k;//极角
    Line () {}
    Line (Point _s, Point _e) {
        s = _s, e = _e;
        k = atan2 (e.y - s.y,e.x - s.x);
    }
    void input () {
        s.input ();
        e.input ();
    }
    void adjust () {
        if (e < s) swap (e, s);
    }
    double length () {//求线段长度
        return dis (s, e);
    }
    void get_angle () {
        k = atan2 (e.y - s.y,e.x - s.x);
    }
};

int relation (Point p, Line l) {//点和直线的关系
    //1:在左侧 2:在右侧 3:在直线上
    int c = dcmp (cross (p-l.s, l.e-l.s));
    if (c < 0) return 1;
    else if (c > 0) return 2;
    else return 3;
}

bool point_on_seg (Point p, Line l) {//判断点在线段上
    return dcmp (cross (p-l.s, l.e-l.s)) == 0 &&
    dcmp (dot (p-l.s, p-l.e) <= 0);
    //如果忽略端点交点改成小于号就好了
}

bool point_on_halfline (Point p, Line l) {//判断点在射线上
    int id = relation (p, l);
    if (id != 3) return 0;
    return dcmp (dot (p-l.s, l.e-l.s)) >= 0;
}


double point_to_line (Point p, Line a) {//点到直线的距离
    return fabs (cross (p-a.s, a.e-a.s) / a.length ());
}
Point projection (Point p, Line a) {//点在直线上的投影
    return a.s + (((a.e-a.s) * dot (a.e-a.s, p-a.s)) / (a.e-a.s).len2() );
}

Point symmetry (Point p, Line a) {//点关于直线的对称点
    Point q = projection (p, a);
    return Point (2*q.x-p.x, 2*q.y-p.y);
}

//***************圆
struct Circle {
    //圆心 半径
    Point p;
    double r;
    Circle () {}
    Circle (Point _p, double _r) : p(_p), r(_r) {}
    Circle (double a, double b, double _r) {
        p = Point (a, b);
        r = _r;
    }
    void input () {
        p.input ();
        scanf ("%lf", &r);
    }
    void output () {
        p.output ();
        printf (" %.2f\n", r);
    }
};
int relation (Line a, Circle b) {//直线和圆的关系
    //0:相离 1:相切 2:相交
    double p = point_to_line (b.p, a);
    if (dcmp (p-b.r) == 0) return 1;
    return (dcmp (p-b.r) < 0 ? 2 : 0);
}

int line_circle_intersection (Line v, Circle u, Point &p1, Point &p2) {//直线和圆的交点
    //返回交点个数 交点保存在引用中
    if (!relation (v, u)) return 0;
    Point a = projection (u.p, v);
    double d = point_to_line (u.p, v);
    d = sqrt (u.r*u.r - d*d);
    if (dcmp (d) == 0) {
        p1 = a, p2 = a;
        return 1;
    }
    p1 = a + (v.e-v.s).change_len (d);
    p2 = a - (v.e-v.s).change_len (d);
    return 2;
}

Circle c;
Point a, b, v;
Point p1, p2;

bool solve () {
    Point aa = a+v;
    Line pre = Line (a, aa);
    int cnt = line_circle_intersection (pre, c, p1, p2);
    if (cnt < 2) {
        if (point_on_halfline (b, pre))
            return 1;
        else
            return 0;
    }
    if (dis (p1, a) > dis (p2, a)) p1 = p2;
    Line Seg (a, p1);
    if (point_on_seg (b, Seg))
        return 1;
    Line faxian (p1, c.p);
    aa = symmetry (a, faxian);
    Line now (p1, aa);
    if (point_on_halfline (b, now))
        return 1;
    return 0;
}

int main () {
    int t, kase = 0;
    scanf ("%d", &t);
    while (t--) {
        printf ("Case #%d: ", ++kase);
        c.p.input (), scanf ("%lf", &c.r);
        a.input (), v.input (), b.input ();
        puts (solve () ? "Yes" : "No");
    }
    return 0;
}

/*
10
0 1 1
-1 0 1 0
100000 0
0 1 1
-1 0 1 1
5 5
0 1 1
0 -99 0 12345
0 -100
*/
hdu 5572 An Easy Physics Problem(几何) 题目链接:hdu 5572 An Easy Physics Problem解题思路注意精度误差,发射的情况可以对应求出B点的对称点再判断代码#include <cstdio> #include <cstring> #include <cmath> #include <algorithm>using namespace std; const double eps = 1e-8; const doubl 阅读详情

相关推荐

HDU 5572-An Easy Physics Problem (计算几何)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5572题目大意: 有一个无体积的球,近似为质点,一开始给出球的初始位置和运动方向(为从原点到给出点的向量方向),同时平面中有一个圆柱体,给出圆心位置和半径,若球撞击圆柱体,则产生以撞击点切线为反射面的无损反弹,求问球是否会经过给定的P点分析: 大体上可以分成两类情况,球会撞击圆柱或者不会撞击圆柱

SD_Stjean的博客 420

HDU - 5572 An Easy Physics Problem(几何-碰撞问题)

题目链接:点击查看 题目大意:在一个二维平面上,给出一个实心圆柱体,再给出一个可以视为质点的小球,小球初始时位于点 A ,会给出一个速度向量 VA,当小球碰到圆柱体时,会因碰撞弹开,规定碰撞不会丢失动能,问在小球在运动的过程中能不能到达点 B 题目分析:稍微画一下图: 为了方便表示射线,我在无穷远处计算出了一个点 inf,这样射线 A就转换为了线段 ( A , inf ),同理图中的 l1 和 l3 都是以线段表示的射线,图中点 P 表示为圆心,G1 和 G2 表示 l1 与圆的两个交点,规定 .

Falcon的博客 564

An Easy Physics Problem HDU - 5572(直线与圆的关系)

这个题直接自闭到结尾 定义p1_1(为p1的方向点)首先判断p1_1与p1的直线与圆的交点如果交点个数小于等于2个只要判断p2点与p1到p1_1的方向向量同向(判断方法为叉积为0说明平行点积大于0说明同向) 当直线与圆交点的个数为2时,这时候情况比较特殊,p3_1为与圆的交点离p1最近的点,情况1:p1的方向刚好是往圆那个方向上走去,并且p2点刚好在p1与p3_1这条线段上这时候肯定能碰到!!...

leekerian的博客 224

HDU 5572(圆的应用)

HDU 5572 题目 : An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description On an infinite smooth table, there’s a big round fixed cylinder and a little ball whose volume can be ignored. Curren

沐白白的博客 470

hdu 5572

#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <map> #include <queue> #include <stdlib.h> #include <cmath> #include <vector> #include <stack>#define clr(x) mems

hzk123的博客 404

HDU5572平面几何问题

HDU 5572An Easy Physics Problem题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 给定圆柱体圆心坐标,半径 小球起点坐标,起始运动方向(向量) 终点坐标 问能否到达终点,小球运动中如果碰到圆柱体会反射(基本物理知识)思路: 根据高中平面几何知识很快找到判断方法,但是向量的代码实现有一些麻烦,浪费时间,使用平面几何向量模板会方便许多#include<cst

Daniel 1002

HDU5572(计算几何+精度)

原题:HDU5572 关于精度:关于精度 点关于直线对称公式: 点( x , y )关于直线Ax + by + C = 0 的对称点( X , Y ): 设参数方程 联立圆方程得到关于t的一元二次方程 可见c>0恒成立 分两种情况讨论: 1.小球不反弹 2(1).小球在反弹前已经经过B点 (2).小球反弹后经过b点 对于1,直

West___wind的博客 1047

HDU 5572 An Easy Physics Problem (计算几何+对称点模板)

HDU 5572 An Easy Physics Problem (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5572 Description On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volume c...

weixin_30808253的博客 114

hdu 5572 An Easy Physics Problem

传送门; http://acm.hdu.edu.cn/showproblem.php?pid=5572上海区域赛铜牌题!!! 令我永生难忘的一道题,当时我们队就是被这道题一直卡着,直接导致最终打铁。。。。当时被气球颜色弄偏了,导致看了一道废题。。。。真的是战略出问题了。题意: 给出初始点和速度向量,有一个圆,和目标点,可以反弹,问最终能不能碰撞。计算几何题: 套一下板子,注意讨论就好了,要注

yp_2013的博客 692

HDU 5572 An Easy Physics Problem 【直线与圆的关系】

传送门:HDU 5572 An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description On an infinite smooth table, there’s a big round fixed ...

Waiting For You 184

hdu5572(计算几何)

An Easy Physics ProblemTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3497    Accepted Submission(s): 690Problem DescriptionOn an infinite smoo...

yypurpose的博客 539

HDU 5572 An Easy Physics Problem【计算几何】

计算几何的题做的真是少之又少。 之前wa以为是精度问题,后来发现是情况没有考虑全。。。题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5572题意:给定起点A和方向V,路径中遇到圆柱体会发生折射,问能否到达终点B。分析:将路径表示为a+t∗va + t * v得到关于tt的二元方程组,求出Δ\Delta。 Δ\Delta小于等于0时,表示不会发生折射

Tuesday 763

HDU5572 2015ICPC上海A计算几何

题目 HDU 5572 无限大的平面上,有一个圆柱。圆柱外有两个点A、B,点A有个速度向量V,A撞到圆柱会发生完全弹性碰撞。问点A是否能经过点B。 解题思路 我们记A -> A+V的运动轨迹为直线 l1l1l1(射线在代码实现中并不好处理)。 共分以下几种情况: 一、 l1l1l1与圆不相交 判断A是否能直接经过B,即判断向量V⃗、B−A⃗\vec{V}、\vec{B-A}V、B−A​是否同向。 二、 l1l1l1与圆相切 情况同一。 三、 l1l1l1与圆相交 记l1l1l1与圆距离较近的点为X。

陈颜的博客 346

An Easy Physics Problem HDU - 5572 直线与圆

//#include //#pragma comment(linker, "/STACK:1024000000,1024000000") #include #include #include #include #include #include #include #include #include #include using namespace std; const double pi=ac

Dream in the Night 322

hdu5572An Easy Physics Problem+计算几何

An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1501 Accepted Submission(s): 289Problem Description On an infinite

xtulollipop 1234

hdu 5572 An Easy Physics Problem(数学)

http://acm.hdu.edu.cn/showproblem.php?pid=5572   题意就是在一个二维空间中给一个起点终点 再给一个圆形弹性区域,起点给定一个方向,在这个空间中速度大小不变。 问起点能否在给定的方向下运动能够到达终点。 这道题难点在于如何判断碰到圆形区域后的速度方向, 不需要去算角度的 只要利用对称点即可, 圆形上的接触点到对称点的方向即为弹出方向 ...

三水的鱼塘♂ 266

HDU 5572 An Easy Physics Problem

题目:点击打开链接 题意:二维平面中一位于(Ax, Ay)的点A以矢量v为方向运动,同时平面内有一半径为r 圆心为Ox Oy的圆,点A碰到圆就会反弹,问运动过程中是否能碰到点B。 分析:这题思路上并不难,写起来比较麻烦,抄的kuangbin的新板子,先判断一下直线AV是否与圆的交点个数,如果少于2个交点,判断B是否在射线AV上,如果有两个交点,求出距离A较近的那个交点P1,求出A关于QP1的对称点...

常胜将军的博客 318
上一篇: HDU 5730 (CDQ分治 FFT)
下一篇: HDU 5755 (高斯消元)
morejarphone
博客等级 码龄12年 54粉丝 462原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值