题目传送门

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

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

  1. /************************************************
  2. * Author :Running_Time
  3. * Created Time :2015/10/24 星期六 16:14:33
  4. * File Name :C.cpp
  5. ************************************************/
  6.  
  7. #include <cstdio>
  8. #include <algorithm>
  9. #include <iostream>
  10. #include <sstream>
  11. #include <cstring>
  12. #include <cmath>
  13. #include <string>
  14. #include <vector>
  15. #include <queue>
  16. #include <deque>
  17. #include <stack>
  18. #include <list>
  19. #include <map>
  20. #include <set>
  21. #include <bitset>
  22. #include <cstdlib>
  23. #include <ctime>
  24. using namespace std;
  25.  
  26. #define lson l, mid, rt << 1
  27. #define rson mid + 1, r, rt << 1 | 1
  28. typedef long long ll;
  29. const int N = 1e5 + 10;
  30. const int INF = 0x3f3f3f3f;
  31. const int MOD = 1e9 + 7;
  32. const double EPS = 1e-10;
  33. int dcmp(double x) { //三态函数,减少精度问题
  34. if (fabs (x) < EPS) return 0;
  35. else return x < 0 ? -1 : 1;
  36. }
  37. struct Point { //点的定义
  38. double x, y;
  39. Point (double x=0, double y=0) : x (x), y (y) {}
  40. Point operator + (const Point &r) const { //向量加法
  41. return Point (x + r.x, y + r.y);
  42. }
  43. Point operator - (const Point &r) const { //向量减法
  44. return Point (x - r.x, y - r.y);
  45. }
  46. Point operator * (double p) { //向量乘以标量
  47. return Point (x * p, y * p);
  48. }
  49. Point operator / (double p) { //向量除以标量
  50. return Point (x / p, y / p);
  51. }
  52. bool operator < (const Point &r) const { //点的坐标排序
  53. return x < r.x || (x == r.x && y < r.y);
  54. }
  55. bool operator == (const Point &r) const { //判断同一个点
  56. return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
  57. }
  58. };
  59. typedef Point Vector; //向量的定义
  60. Point read_point(void) { //点的读入
  61. double x, y;
  62. scanf ("%lf%lf", &x, &y);
  63. return Point (x, y);
  64. }
  65. double polar_angle(Vector A) { //向量极角
  66. return atan2 (A.y, A.x);
  67. }
  68. double dot(Vector A, Vector B) { //向量点积
  69. return A.x * B.x + A.y * B.y;
  70. }
  71. double cross(Vector A, Vector B) { //向量叉积
  72. return A.x * B.y - A.y * B.x;
  73. }
  74. double length(Vector A) { //向量长度,点积
  75. return sqrt (dot (A, A));
  76. }
  77. double angle(Vector A, Vector B) { //向量转角,逆时针,点积
  78. return acos (dot (A, B) / length (A) / length (B));
  79. }
  80. double area_triangle(Point a, Point b, Point c) { //三角形面积,叉积
  81. return fabs (cross (b - a, c - a)) / 2.0;
  82. }
  83. Vector rotate(Vector A, double rad) { //向量旋转,逆时针
  84. return Vector (A.x * cos (rad) - A.y * sin (rad), A.x * sin (rad) + A.y * cos (rad));
  85. }
  86. Vector nomal(Vector A) { //向量的单位法向量
  87. double len = length (A);
  88. return Vector (-A.y / len, A.x / len);
  89. }
  90. Point point_inter(Point p, Vector V, Point q, Vector W) { //两直线交点,参数方程
  91. Vector U = p - q;
  92. double t = cross (W, U) / cross (V, W);
  93. return p + V * t;
  94. }
  95. double dis_to_line(Point p, Point a, Point b) { //点到直线的距离,两点式
  96. Vector V1 = b - a, V2 = p - a;
  97. return fabs (cross (V1, V2)) / length (V1);
  98. }
  99. double dis_to_seg(Point p, Point a, Point b) { //点到线段的距离,两点式
  100.  
  101. if (a == b) return length (p - a);
  102. Vector V1 = b - a, V2 = p - a, V3 = p - b;
  103. if (dcmp (dot (V1, V2)) < 0) return length (V2);
  104. else if (dcmp (dot (V1, V3)) > 0) return length (V3);
  105. else return fabs (cross (V1, V2)) / length (V1);
  106. }
  107. Point point_proj(Point p, Point a, Point b) { //点在直线上的投影,两点式
  108. Vector V = b - a;
  109. return a + V * (dot (V, p - a) / dot (V, V));
  110. }
  111. bool inter(Point a1, Point a2, Point b1, Point b2) { //判断线段相交,两点式
  112. double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
  113. c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
  114. return dcmp (c1) * dcmp (c2) < 0 && dcmp (c3) * dcmp (c4) < 0;
  115. }
  116. bool on_seg(Point p, Point a1, Point a2) { //判断点在线段上,两点式
  117. return dcmp (cross (a1 - p, a2 - p)) == 0 && dcmp (dot (a1 - p, a2 - p)) < 0;
  118. }
  119. double area_poly(Point *p, int n) { //多边形面积
  120. double ret = 0;
  121. for (int i=1; i<n-1; ++i) {
  122. ret += fabs (cross (p[i] - p[0], p[i+1] - p[0]));
  123. }
  124. return ret / 2;
  125. }
  126. /*
  127. 点集凸包,输入点集会被修改
  128. */
  129. vector<Point> convex_hull(vector<Point> &P) {
  130. sort (P.begin (), P.end ());
  131. P.erase (unique (P.begin (), P.end ()), P.end ()); //预处理,删除重复点
  132. int n = P.size (), m = 0;
  133. vector<Point> ret (n + 1);
  134. for (int i=0; i<n; ++i) {
  135. while (m > 1 && cross (ret[m-1]-ret[m-2], P[i]-ret[m-2]) < 0) m--;
  136. ret[m++] = P[i];
  137. }
  138. int k = m;
  139. for (int i=n-2; i>=0; --i) {
  140. while (m > k && cross (ret[m-1]-ret[m-2], P[i]-ret[m-2]) < 0) m--;
  141. ret[m++] = P[i];
  142. }
  143. if (n > 1) m--;
  144. ret.resize (m);
  145. return ret;
  146. }
  147.  
  148. struct Circle {
  149. Point c;
  150. double r;
  151. Circle () {}
  152. Circle (Point c, double r) : c (c), r (r) {}
  153. Point point(double a) {
  154. return Point (c.x + cos (a) * r, c.y + sin (a) * r);
  155. }
  156. };
  157.  
  158. struct Line {
  159. Point p;
  160. Vector v;
  161. double r;
  162. Line () {}
  163. Line (const Point &p, const Vector &v) : p (p), v (v) {
  164. r = polar_angle (v);
  165. }
  166. Point point(double a) {
  167. return p + v * a;
  168. }
  169. };
  170.  
  171. /*
  172. 直线相交求交点,返回交点个数,交点保存在P中
  173. */
  174. int line_cir_inter(Line L, Circle C, double &t1, double &t2, vector<Point> &P) {
  175. double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
  176. double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
  177. double delta = f * f - 4 * e * g;
  178. if (dcmp (delta) < 0) return 0;
  179. if (dcmp (delta) == 0) {
  180. t1 = t2 = -f / (2 * e); P.push_back (L.point (t1));
  181. return -1;
  182. }
  183. t1 = (-f - sqrt (delta)) / (2 * e); P.push_back (L.point (t1));
  184. t2 = (-f + sqrt (delta)) / (2 * e); P.push_back (L.point (t2));
  185. if (dcmp (t1) < 0 || dcmp (t2) < 0) return 0;
  186. return 2;
  187. }
  188.  
  189. /*
  190. 两圆相交求交点,返回交点个数。交点保存在P中
  191. */
  192. int cir_cir_inter(Circle C1, Circle C2, vector<Point> &P) {
  193. double d = length (C1.c - C2.c);
  194. if (dcmp (d) == 0) {
  195. if (dcmp (C1.r - C2.r) == 0) return -1; //两圆重叠
  196. else return 0;
  197. }
  198. if (dcmp (C1.r + C2.r - d) < 0) return 0;
  199. if (dcmp (fabs (C1.r - C2.r) - d) < 0) return 0;
  200. double a = polar_angle (C2.c - C1.c);
  201. double da = acos ((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d)); //C1C2到C1P1的角?
  202. Point p1 = C1.point (a - da), p2 = C2.point (a + da);
  203. P.push_back (p1);
  204. if (p1 == p2) return 1;
  205. else P.push_back (p2);
  206. return 2;
  207. }
  208.  
  209. int main(void) {
  210. Circle C1, C2; Point a, b;
  211. double Rm, R, r, x, y, vx, vy;
  212. while (scanf ("%lf%lf%lf%lf%lf%lf%lf", &Rm, &R, &r, &x, &y, &vx, &vy) == 7) {
  213. Rm += r; R += r;
  214. C1 = Circle (Point (0, 0), Rm);
  215. C2 = Circle (Point (0, 0), R);
  216. a = Point (x, y); b = Point (vx, vy);
  217. vector<Point> P1, P2; P1.clear (); P2.clear ();
  218. double t1, t2, t3, t4, ans, speed = sqrt (vx * vx + vy * vy);
  219. int num1 = line_cir_inter (Line (a, b), C1, t1, t2, P1);
  220. int num2 = line_cir_inter (Line (a, b), C2, t3, t4, P2);
  221. if (num2 == 2) {
  222. if (num1 == 2) {
  223. double len = length (P2[0] - P2[1]) - length (P1[0] - P1[1]);
  224. ans = len / speed;
  225. }
  226. else {
  227. ans = length (P2[0] - P2[1]) / speed;
  228. }
  229. }
  230. else {
  231. ans = 0.0;
  232. }
  233. printf ("%.4f\n", ans);
  234. }
  235.  
  236. return 0;
  237. }

  

简单几何(直线与圆的交点) 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. Unity 烘焙材质到单一贴图的脚本

    原地址:http://www.cocoachina.com/gamedev/gameengine/2011/0406/2756.html 这个脚本由 CocoaChina 版主 “四角钱” 分享,可以 ...

  2. 【Python】Python AES 对称加密示例

    代码: import sys from Crypto.Cipher import AES from binascii import b2a_hex, a2b_hex AES_SECRET_KEY = ...

  3. C++ virtual descructor

    [代码1]  C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546 ...

  4. 无论IT代码系统还是人生都是有惯性的

    是的,这和IT系统和代码没有什么关系:鸡汤式的文章,看烦了的就关掉吧,想看的请听我碎碎念.惯性本是物理学研究的问题,这里没有要研究物理学里的惯性.惯性无时无刻地发生在我们的日常生活中,只是你我都没有察 ...

  5. Android studio 程序升级和sdk manager 升级方法

    在中国使用android有点郁闷,经常被屏蔽.常遇到2个升级问题,现在总结如下:  1.android studio升级时提示 Connection failed. Please check your ...

  6. zpf 命名规则

    2014年8月19日 18:48:39 所有控制器都要继承main类,main类是一个入口类,他里边根据请求初始化了一些变量,也初始化了一些系统变量等等,这些变量和函数可以被控制器类直接使用 控制器类 ...

  7. 【python】2048

    来源:https://www.shiyanlou.com/courses/368 实验楼的2048程序,在linux下可实现通过终端游戏. 主要学习的知识点: 1.状态机函数实现,用字典将状态和函数相 ...

  8. 播放视频最好的 HTML 解决方法

    HTML 5 + <object> + <embed> <video width=" controls="controls"> < ...

  9. mongoose学习笔记3--简单查询1

    简述 查询就是返回一个集合中的文档的子集 Mongoose 模型提供了 find. findOne. findById 三种方法用于文档查询. 为了方便后面课程的有效学习,我们先添加一些测试数据. T ...

  10. surface RT app安装心得

    打开store,然后在键盘输入字母,就出现搜索栏了. 想安装qq,但是输入后找不到软件,原因是我在初始化系统的时候,我的所在地选择的是新加坡,因此找不到软件.在屏幕右下方的setting,然后将所在地 ...