题目传送门

题意:有两个一大一小的同心圆,圆心在原点,大圆外有一小圆,其圆心有一个速度(vx, vy),如果碰到了小圆会反弹,问该圆在大圆内运动的时间

分析:将圆外的小圆看成一个点,判断该直线与同心圆的交点,根据交点个数计算时间。用到了直线的定义,圆的定义,直线与圆交点的个数。

/************************************************
* Author :Running_Time
* Created Time :2015/10/24 星期六 16:14:33
* File Name :C.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
int dcmp(double x) { //三态函数,减少精度问题
if (fabs (x) < EPS) return 0;
else return x < 0 ? -1 : 1;
}
struct Point { //点的定义
double x, y;
Point (double x=0, double y=0) : x (x), y (y) {}
Point operator + (const Point &r) const { //向量加法
return Point (x + r.x, y + r.y);
}
Point operator - (const Point &r) const { //向量减法
return Point (x - r.x, y - r.y);
}
Point operator * (double p) { //向量乘以标量
return Point (x * p, y * p);
}
Point operator / (double p) { //向量除以标量
return Point (x / p, y / p);
}
bool operator < (const Point &r) const { //点的坐标排序
return x < r.x || (x == r.x && y < r.y);
}
bool operator == (const Point &r) const { //判断同一个点
return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
}
};
typedef Point Vector; //向量的定义
Point read_point(void) { //点的读入
double x, y;
scanf ("%lf%lf", &x, &y);
return Point (x, y);
}
double polar_angle(Vector A) { //向量极角
return atan2 (A.y, A.x);
}
double dot(Vector A, Vector B) { //向量点积
return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B) { //向量叉积
return A.x * B.y - A.y * B.x;
}
double length(Vector A) { //向量长度,点积
return sqrt (dot (A, A));
}
double angle(Vector A, Vector B) { //向量转角,逆时针,点积
return acos (dot (A, B) / length (A) / length (B));
}
double area_triangle(Point a, Point b, Point c) { //三角形面积,叉积
return fabs (cross (b - a, c - a)) / 2.0;
}
Vector rotate(Vector A, double rad) { //向量旋转,逆时针
return Vector (A.x * cos (rad) - A.y * sin (rad), A.x * sin (rad) + A.y * cos (rad));
}
Vector nomal(Vector A) { //向量的单位法向量
double len = length (A);
return Vector (-A.y / len, A.x / len);
}
Point point_inter(Point p, Vector V, Point q, Vector W) { //两直线交点,参数方程
Vector U = p - q;
double t = cross (W, U) / cross (V, W);
return p + V * t;
}
double dis_to_line(Point p, Point a, Point b) { //点到直线的距离,两点式
Vector V1 = b - a, V2 = p - a;
return fabs (cross (V1, V2)) / length (V1);
}
double dis_to_seg(Point p, Point a, Point b) { //点到线段的距离,两点式 if (a == b) return length (p - a);
Vector V1 = b - a, V2 = p - a, V3 = p - b;
if (dcmp (dot (V1, V2)) < 0) return length (V2);
else if (dcmp (dot (V1, V3)) > 0) return length (V3);
else return fabs (cross (V1, V2)) / length (V1);
}
Point point_proj(Point p, Point a, Point b) { //点在直线上的投影,两点式
Vector V = b - a;
return a + V * (dot (V, p - a) / dot (V, V));
}
bool inter(Point a1, Point a2, Point b1, Point b2) { //判断线段相交,两点式
double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
return dcmp (c1) * dcmp (c2) < 0 && dcmp (c3) * dcmp (c4) < 0;
}
bool on_seg(Point p, Point a1, Point a2) { //判断点在线段上,两点式
return dcmp (cross (a1 - p, a2 - p)) == 0 && dcmp (dot (a1 - p, a2 - p)) < 0;
}
double area_poly(Point *p, int n) { //多边形面积
double ret = 0;
for (int i=1; i<n-1; ++i) {
ret += fabs (cross (p[i] - p[0], p[i+1] - p[0]));
}
return ret / 2;
}
/*
点集凸包,输入点集会被修改
*/
vector<Point> convex_hull(vector<Point> &P) {
sort (P.begin (), P.end ());
P.erase (unique (P.begin (), P.end ()), P.end ()); //预处理,删除重复点
int n = P.size (), m = 0;
vector<Point> ret (n + 1);
for (int i=0; i<n; ++i) {
while (m > 1 && cross (ret[m-1]-ret[m-2], P[i]-ret[m-2]) < 0) m--;
ret[m++] = P[i];
}
int k = m;
for (int i=n-2; i>=0; --i) {
while (m > k && cross (ret[m-1]-ret[m-2], P[i]-ret[m-2]) < 0) m--;
ret[m++] = P[i];
}
if (n > 1) m--;
ret.resize (m);
return ret;
} struct Circle {
Point c;
double r;
Circle () {}
Circle (Point c, double r) : c (c), r (r) {}
Point point(double a) {
return Point (c.x + cos (a) * r, c.y + sin (a) * r);
}
}; struct Line {
Point p;
Vector v;
double r;
Line () {}
Line (const Point &p, const Vector &v) : p (p), v (v) {
r = polar_angle (v);
}
Point point(double a) {
return p + v * a;
}
}; /*
直线相交求交点,返回交点个数,交点保存在P中
*/
int line_cir_inter(Line L, Circle C, double &t1, double &t2, vector<Point> &P) {
double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
double delta = f * f - 4 * e * g;
if (dcmp (delta) < 0) return 0;
if (dcmp (delta) == 0) {
t1 = t2 = -f / (2 * e); P.push_back (L.point (t1));
return -1;
}
t1 = (-f - sqrt (delta)) / (2 * e); P.push_back (L.point (t1));
t2 = (-f + sqrt (delta)) / (2 * e); P.push_back (L.point (t2));
if (dcmp (t1) < 0 || dcmp (t2) < 0) return 0;
return 2;
} /*
两圆相交求交点,返回交点个数。交点保存在P中
*/
int cir_cir_inter(Circle C1, Circle C2, vector<Point> &P) {
double d = length (C1.c - C2.c);
if (dcmp (d) == 0) {
if (dcmp (C1.r - C2.r) == 0) return -1; //两圆重叠
else return 0;
}
if (dcmp (C1.r + C2.r - d) < 0) return 0;
if (dcmp (fabs (C1.r - C2.r) - d) < 0) return 0;
double a = polar_angle (C2.c - C1.c);
double da = acos ((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d)); //C1C2到C1P1的角?
Point p1 = C1.point (a - da), p2 = C2.point (a + da);
P.push_back (p1);
if (p1 == p2) return 1;
else P.push_back (p2);
return 2;
} int main(void) {
Circle C1, C2; Point a, b;
double Rm, R, r, x, y, vx, vy;
while (scanf ("%lf%lf%lf%lf%lf%lf%lf", &Rm, &R, &r, &x, &y, &vx, &vy) == 7) {
Rm += r; R += r;
C1 = Circle (Point (0, 0), Rm);
C2 = Circle (Point (0, 0), R);
a = Point (x, y); b = Point (vx, vy);
vector<Point> P1, P2; P1.clear (); P2.clear ();
double t1, t2, t3, t4, ans, speed = sqrt (vx * vx + vy * vy);
int num1 = line_cir_inter (Line (a, b), C1, t1, t2, P1);
int num2 = line_cir_inter (Line (a, b), C2, t3, t4, P2);
if (num2 == 2) {
if (num1 == 2) {
double len = length (P2[0] - P2[1]) - length (P1[0] - P1[1]);
ans = len / speed;
}
else {
ans = length (P2[0] - P2[1]) / speed;
}
}
else {
ans = 0.0;
}
printf ("%.4f\n", ans);
} return 0;
}

  

简单几何(直线与圆的交点) ZOJ Collision 3728的更多相关文章

  1. 简单几何(直线求交点) POJ 2074 Line of Sight

    题目传送门 题意:从一条马路(线段)看对面的房子(线段),问连续的能看到房子全部的最长区间 分析:自己的思路WA了:先对障碍物根据坐标排序,然后在相邻的障碍物的间隔找到区间,这样还要判断是否被其他障碍 ...

  2. 简单几何(直线与线段相交) POJ 1039 Pipe

    题目传送门 题意:一根管道,有光源从入口发射,问光源最远到达的地方. 分析:黑书上的例题,解法是枚举任意的一个上顶点和一个下顶点(优化后),组成直线,如果直线与所有竖直线段有交点,则表示能穿过管道. ...

  3. 简单几何(直线位置) POJ 1269 Intersecting Lines

    题目传送门 题意:判断两条直线的位置关系,共线或平行或相交 分析:先判断平行还是共线,最后就是相交.平行用叉积判断向量,共线的话也用叉积判断点,相交求交点 /********************* ...

  4. zznuoj 1540 : 直线与圆

    题目描述 给出一个圆的圆心坐标与圆的半径,和一条直线上的两点坐标,求这条直线与圆有多少个交点. 输入 输入3个实数x,y,r值分别表示圆心坐标与圆的半径,输入4个实数x1,y1,x2,y2表示直线上的 ...

  5. Gym - 101617F :Move Away (圆的交点)

    pro:给定N个圆,求离原点最远的点,满足它在N个圆里.输出这个距离.N<50; sol:关键点一定是圆与圆的交点. 圆与 圆心到原点的直线 的交点. 然后去验证这些关键点是否在N个圆内. 实际 ...

  6. HDU 5572--An Easy Physics Problem(射线和圆的交点)

    An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  7. 【python+opencv】直线检测+圆检测

     Python+OpenCV图像处理—— 直线检测 直线检测理论知识: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进 ...

  8. Python下opencv使用笔记(二)(简单几何图像绘制)

    简单几何图像一般包含点.直线.矩阵.圆.椭圆.多边形等等.首先认识一下opencv对像素点的定义. 图像的一个像素点有1或者3个值.对灰度图像有一个灰度值,对彩色图像有3个值组成一个像素值.他们表现出 ...

  9. hough变换检测直线和圆

    图像测量和机器视觉作业: 提取图像中的直线和点的位置坐标,将其按一定顺序编码存入一文本文件,并在原图像上叠加显示出来. 下午实验了一下: 程序环境:vs2013(活动平台为x64)+opencv3.1 ...

随机推荐

  1. js检测是否安装了flash插件

    function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //flash版本 var isIE = ...

  2. Hessian原理分析

    一.      远程通讯协议的基本原理 网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http . tcp . udp 等等, ...

  3. Unique Binary Search Trees I & II

    Given n, how many structurally unique BSTs (binary search trees) that store values 1...n? Example Gi ...

  4. eclipse debug source not fount

    1.选择Edit Source Lookup Path 2.选择Add 3.选择Java Project 4.选择相应的Project 进行OK确定即可 注意:做完以上的操作,要清除一下原来的断点,然 ...

  5. 【转】PowerDesigner使用方法小结

    本文转自:http://www.cnblogs.com/afarmer/archive/2012/11/05/2755327.html PowerDesigner多用来进行数据库模型设计,具有SQL语 ...

  6. (转)SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)

    二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编 ...

  7. Java for LeetCode 201 Bitwise AND of Numbers Range

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  8. Eclipse调试:F5、F6、F7、F8

    F5:跳入方法 F6:向下逐行调试 F7:跳出方法 F8:直接跳转到下一个断点 转载自:http://blog.sina.com.cn/s/blog_6271df6f0101d856.html

  9. HTML5-------元素使用

    HTML5的元素使用

  10. ListView滑动删除效果实现

    通过继承ListView然后结合PopupWindow实现 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" ...