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 operator - (Point a,Point b)
{
    return Point(a.x-b.x,a.y-b.y);
}

double dist(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double multi(Point a,Point b)
{
    return a.x*b.x+a.y*b.y;
}

double cross(Point a,Point b)
{
    return a.x*b.y-a.y*b.x;
}

Point TriangleCircumCenter(Point a,Point b,Point c)
{
    Point res;
    double a1=atan2(b.y-a.y,b.x-a.x)+pi/2;
    double a2=atan2(c.y-b.y,c.x-b.x)+pi/2;
    double ax=(a.x+b.x)/2;
    double ay=(a.y+b.y)/2;
    double bx=(c.x+b.x)/2;
    double by=(c.y+b.y)/2;
    double r1=(sin(a2)*(ax-bx)+cos(a2)*(by-ay))/(sin(a1)*cos(a2)-sin(a2)*cos(a1));
    return Point(ax+r1*cos(a1),ay+r1*sin(a1));
}

int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int x1,y1,x2,y2,x3,y3,xp,yp;
    int kase=0;
    while(~scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&xp,&yp))
    {
        Point p1=Point(x1,y1);
        Point p2=Point(x2,y2);
        Point p3=Point(x3,y3);
        Point pp=Point(xp,yp);
        Point pc=TriangleCircumCenter(p1,p2,p3);    //算圆心
        double temp=cross(p2-p1,p3-p1);
        if(temp<0)  //如果是顺时针,把p1和p3点互换
        {
            Point t=p1;
            p1=p3;
            p3=t;
        }
        double cosA=multi(p1-pc,p3-pc)/(dist(p1,pc)*dist(p3,pc));
        if(fabs(cosA)>1)    //如果fabs(cosA)>1,那么acos(cosA)算出的结果是不合法的
        {
            if(cosA<0) cosA+=eps;
            else cosA-=eps;
        }
        double maxd=acos(cosA); //算p1-pc与p3-pc的夹角
        if(cross(p1-pc,p3-pc)<0 && fabs(cross(p1-pc,p3-pc))>eps)
            maxd=2*pi-maxd;
        double cosB=multi(p1-pc,pp-pc)/(dist(p1,pc)*dist(pp,pc));
        if(fabs(cosB)>1)
        {
            if(cosB<0) cosB+=eps;
            else cosB-=eps;
        }
        double degree=acos(cosB);   //算p1-pc与pp-pc的夹角
        if(cross(p1-pc,pp-pc)<0 && fabs(cross(p1-pc,pp-pc))>eps)
            degree=2*pi-degree;
        if(degree<maxd)
            printf("Case %d: %.3lf\n",++kase,fabs(dist(pp,pc)-dist(p1,pc)));
        else
            printf("Case %d: %.3lf\n",++kase,min(dist(pp,p1),dist(pp,p3)));
    }
    return 0;
}
时间: 2024-11-06 02:38:17

csu-acm 1503: 点到圆弧的距离的相关文章

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 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 点到圆弧的距离(2014湖南省程序设计竞赛A题)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503 解题报告:分两种情况就可以了,第一种是那个点跟圆心的连线在那段扇形的圆弧范围内,这样的话点到圆弧的最短距离就是点到圆心的距离减去半径然后再取绝对值就可以了,第二种情况是那个点跟圆心的连线不在那段扇形的圆弧范围内,这样的话,最短的距离就是到这段圆弧的端点的最小值. 接下来的第一步就是求圆心的坐标跟圆的半径,只要求出圆心坐标半径就好说了,求圆心坐标我用的方法是: 设圆心坐标是(a,b

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

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

点到圆弧的距离(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组数据.每组

5-7 点到原点的距离(多态)

给出下面的一个基类框架: class Point { protected: int dimension;//点的维数,最多不超过100维 private: int point_length[100]://点数组 public: Point ();//构造函数根据需要重载 float distance( );//计算当前点到原点的距离 void display();//输出点 } 以Point为基类建一个派生类Point_2D,增加以下数据成员: float x;//2D平面上点的x坐标 floa

POJ1584 判断多边形是否为凸多边形,并判断点到直线的距离

求点到直线的距离: double dis(point p1,point p2){   if(fabs(p1.x-p2.x)<exp)//相等的  {    return fabs(p2.x-pegx);    }  else     {   double k=(p2.y-p1.y)/(p2.x-p1.x);   double b=p2.y-k*p2.x;   return fabs(k*pegx-pegy+b)/sqrt(k*k+1);//返回的是距离的   }}判断多边形是否为凸多边形 if

URAL 1348 Goat in the Garden 2(点到线段的距离)

[题目链接]:click here~~ [题目大意]:求某点到一条线段的最小距离与最大距离. [思路]: 分析可知,最大距离一定在端点处取得.那么接下来求最小距离时,先求出垂线与线段所在直线的交点,然后判断交点在不在线段上.如果在,则最小距离为垂线段的距离,即交点到此点的距离.如果不在,则最小距离必在另一端点取得.问题转换如何判断点与线段的垂足是否在线段上,可以利用叉积方便的求出. 代码: /* * Problem: NO:URAL 1348 * Running time: 1MS * Comp

poj1584 A Round Peg in a Ground Hole 判断多边形凹凸,点到线的距离【基础计算几何】

大致思路:首先对于所给的洞的点,判断是否是凸多边形,图形的输入和输出可以是顺时针或者逆时针,而且允许多点共线 Debug 了好几个小时,发现如下问题 判断三点是否共线,可用斜率公式判断 POINT point_A, point_B, point_C; if(point_A.x == point_B.x || point_B.x == point_C.x){ if(point_A.x == point_B.x && point_B.x == point_C.x) continue; }els