CSU 1503 点到圆弧的距离(2014湖南省程序设计竞赛A题)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503

解题报告:分两种情况就可以了,第一种是那个点跟圆心的连线在那段扇形的圆弧范围内,这样的话点到圆弧的最短距离就是点到圆心的距离减去半径然后再取绝对值就可以了,第二种情况是那个点跟圆心的连线不在那段扇形的圆弧范围内,这样的话,最短的距离就是到这段圆弧的端点的最小值。

接下来的第一步就是求圆心的坐标跟圆的半径,只要求出圆心坐标半径就好说了,求圆心坐标我用的方法是:

设圆心坐标是(a,b),然后列方程:

(x1-a)^2 + (y1-b)^2 = r^2;

(x2-a)^2 + (y2-b)^2 = r^2;

(x3-a)^2 + (y3-b)^2 = r^2;

然后这样的话,计算过程中会出现y2-y1做分母的情况,所以,我又分了两种情况来讨论。

求出圆心坐标然后接下来的问题就只有怎么判断那个点跟圆心的连线是不是在扇形的圆弧范围内了,我也是用了分情况讨论的,但这里分的情况还是比较多的,一开始分了8种情况,然后压缩了一下,变成4种情况,分别是:

判断给点的顺序是顺时针还是逆时针,然后判断区间的方向,然后就是判断那个点是不是跟p2点在同一个区间就可以了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 const double eps = 1e-6,PI = acos(-1.0);
  8
  9 struct Point
 10 {
 11     double x,y;
 12     friend Point operator - (Point a,Point b)
 13     {
 14         Point temp;
 15         temp.x = a.x - b.x;
 16         temp.y = a.y - b.y;
 17         return temp;
 18     }
 19 };
 20
 21 Point p1,p2,p3,pc,pp;
 22 double r;
 23
 24 Point get_pc1(Point p1, Point p2, Point p3)    //求圆心
 25 {
 26   Point p;
 27   if(fabs(p1.y-p2.y) > eps)      //因为计算过程中有出现(y2-y1)做分母的情况,所以这里分了两种情况讨论
 28   {
 29  //      double t1 = p3.x*p3.x - p1.x*p1.x+p3.y*p3.y-p1.y*p1.y-((p3.y-p1.y)*(p1.x*p1.x-p2.x*p2.x+p1.y*p1.y-p2.y*p2.y)) / (p2.y-p1.y);
 30    //    double t2 = 2.0*(p3.x-p1.x)-(2*(p3.y-p1.y)*(p2.x-p1.x)) / (p2.y-p1.y);
 31         double  t1 = (p2.x*p2.x-p1.x*p1.x+p2.y*p2.y-p1.y*p1.y) *(p3.y-p1.y) - (p2.y-p1.y)*(p3.x*p3.x-p1.x*p1.x+p3.y*p3.y-p1.y*p1.y);
 32         double t2 = 2.0*((p3.y-p1.y)*(p2.x-p1.x) - (p2.y-p1.y)*(p3.x-p1.x));
 33        p.x = t1 / t2;
 34        p.y = (p2.x*p2.x-p1.x*p1.x+p2.y*p2.y-p1.y*p1.y-2*(p2.x-p1.x)*p.x) / (2*(p2.y-p1.y));
 35     }
 36     else
 37     {
 38         p.x = (p2.x*p2.x-p1.x*p1.x+p2.y*p2.y-p1.y*p1.y) / (2*(p2.x-p1.x));
 39         p.y = (p3.x*p3.x-p1.x*p1.x+p3.y*p3.y-p1.y*p1.y-2*(p3.x-p1.x)*p.x) / (2*(p3.y-p1.y));
 40     }
 41     return p;
 42 }
 43 double dis(Point a,Point b)
 44 {
 45     return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
 46 }
 47 double mult_ca(Point p1,Point p2)   //叉乘
 48 {
 49     return p1.x * p2.y - p2.x * p1.y;
 50 }
 51
 52 double get_ans(Point pc,Point pp,Point p1,Point p2,Point p3)
 53 {
 54     double temp = mult_ca(p2-p1,p3-p1);
 55     double f1 = atan2((p1-pc).x,(p1-pc).y);
 56     double f2 = atan2((p3-pc).x,(p3-pc).y);
 57     double f3 = atan2((p2-pc).x,(p2-pc).y);
 58     double f4 = atan2((pp-pc).x,(pp-pc).y);
 59     double ans1 = fabs(dis(pp,pc)-dis(p1,pc));
 60     double ans2 = min(dis(pp,p1),dis(pp,p3));
 61     if(temp < 0)    //顺时针给点
 62     {
 63         if(f1 < f2)      //判断区间方向,这样有利于判断p点和p2点是不是在同一个区间
 64         {
 65             if((f3 >= f1 && f3 <= f2) == (f4 >= f1 && f4 <= f2) ) return ans1;
 66             else return ans2;
 67         }
 68         else
 69         {
 70             if((f3 >= f2 && f3 <= f1) == (f4 >=f2 && f4 <= f1) ) return ans1;
 71             else return ans2;
 72         }
 73     }
 74     else
 75     {
 76         if(f2 < f1)
 77         {
 78             if((f3 >= f2 && f3 <= f1) == (f4 >= f2 && f4 <= f1) ) return ans1;
 79             else return ans2;
 80         }
 81         else
 82         {
 83             if((f3 >= f1 && f3 <= f2) == (f4 >= f1 && f4 <= f2)) return ans1;
 84             else return ans2;
 85         }
 86     }
 87 }
 88
 89 int main()
 90 {
 91   //   freopen("in","r",stdin);
 92     int kase = 1;
 93     while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y,&p3.x,&p3.y,&pp.x,&pp.y)!=EOF)
 94     {
 95         pc = get_pc1(p1,p2,p3);
 96         double ans = get_ans(pc,pp,p1,p2,p3);
 97         printf("Case %d: %.3lf\n",kase++,ans);
 98     }
 99     return 0;
100 }

时间: 2024-08-01 18:37:04

CSU 1503 点到圆弧的距离(2014湖南省程序设计竞赛A题)的相关文章

CSU 1503: 点到圆弧的距离(计算几何)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503 Description 输入一个点P和一条圆弧(圆周的一部分),你的任务是计算P到圆弧的最短距离.换句话说,你需要在圆弧上找一个点,到P点的距离最小. 提示:请尽量使用精确算法.相比之下,近似算法更难通过本题的数据. Input 输入包含最多10000组数据.每组数据包含8个整数x1, y1, x2, y2, x3, y3, xp, yp.圆弧的起点是A(x1,y1),经过点B(

csu 1503: 点到圆弧的距离-湖南省第十届大学生计算机程序设计竞赛

就是--判断p与圆心的连线与圆的交点在不在圆弧上,在就是它到p的距离,不在就是p跟端点的最短距离 #include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector>

CSU 1337 搞笑版费马大定理(2013湖南省程序设计竞赛J题)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1337 解题报告:虽然x和y的范围都是10^8,但是如果a 是大于1000的话,那么a^3就会大于10^9,这样等号的右边只有一个10 * c + 3,这个最大只能达到10^9数量级,所以,不管输入的x跟y是多少,我们只要取其中的在1到1000的区间就可以了,枚举a和b,那么c就可以得到,然后判断c的范围是不是在x到y之间,这样时间复杂度就降到了10^6. 1 #include<cstd

csuoj 1503: 点到圆弧的距离

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503 1503: 点到圆弧的距离 时间限制: 1 Sec  内存限制: 128 MB  Special Judge 提交: 247  解决: 59 [提交][状态][讨论版] 题目描述 输入一个点P和一条圆弧(圆周的一部分),你的任务是计算P到圆弧的最短距离.换句话说,你需要在圆弧上找一个点,到P点的距离最小. 提示:请尽量使用精确算法.相比之下,近似算法更难通过本题的数据. 输入 输入包含最多

csu-acm 1503: 点到圆弧的距离

1503: 点到圆弧的距离 分析: 先判断点和圆心的连线是否在圆弧范围内,如果在,最短距离即到圆心的距离减去半径的绝对值:反之,为到端点的最短距离. 具体看注释 #include <bits/stdc++.h> using namespace std; #define eps 1e-8 const double pi=acos(-1); struct Point { double x,y; Point(double a=0,double b=0) { x=a; y=b; } }; Point

2012年湖南省程序设计竞赛E题 最短的名字

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1115 解题报告:输入n个字符串,让你求出可以用来区别这些字符串的最少的前缀总共有多少个字母.可以区别是指每个字符串都取一个自己的前缀,同时保证所有取的这些前缀没有完全相同. 这题用字典树可以做,就是输入的时候把所有的字符串都插入到字典树中,最后把所有被走过不止一次的节点的值都加起来,每个节点的值表示这个节点被走过多少次,然后如果碰到这个节点的值是1的时候总和加1,同时要退出,后面的就不

CSU 1328 近似回文词(2013湖南省程序设计竞赛A题)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 解题报告:中文题题意就不说了.还好数据不大,只有1000,枚举回文串的中心位置,然后向两边扩展,当扩展到 k 大于要求的K的时候停止扩展,不断更新最长的长度跟开始位置最小.我先做了个预处理,先求出了a(S),然后用一个数组保存了a(S)中的字符在原来的字符串中对应的位置在哪,这样便于字符串比较,而且又可以在O(1)时间得到在原来串中的长度跟开始的位置. 1 #include<cs

点到圆弧的距离(csu1503)+几何

1503: 点到圆弧的距离 Time Limit: 1 Sec  Memory Limit: 128 MB  Special JudgeSubmit: 325  Solved: 70[Submit][Status][Web Board] Description 输入一个点P和一条圆弧(圆周的一部分),你的任务是计算P到圆弧的最短距离.换句话说,你需要在圆弧上找一个点,到P点的距离最小.提示:请尽量使用精确算法.相比之下,近似算法更难通过本题的数据. Input 输入包含最多10000组数据.每组

angry_birds_again_and_again(2014年山东省第五届ACM大学生程序设计竞赛A题)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2877 题目描述 The problems called "Angry Birds" and "Angry Birds Again and Again" has been solved by many teams in the series of contest in 2011 Multi-University Tr