zoukankan      html  css  js  c++  java
  • hdu 6097 Mindis(数学几何,圆心的反演点)

    Mindis

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2787    Accepted Submission(s): 555
    Special Judge

    Problem Description
    The center coordinate of the circle C is O, the coordinate of O is (0,0) , and the radius is r.
    P and Q are two points not outside the circle, and PO = QO.
    You need to find a point D on the circle, which makes PD+QD minimum.
    Output minimum distance sum.
     
    Input
    The first line of the input gives the number of test cases T; T test cases follow.
    Each case begins with one line with r : the radius of the circle C.
    Next two line each line contains two integers x , y denotes the coordinate of P and Q.

    Limits
    T500000
    100x,y100
    1r100
     
    Output
    For each case output one line denotes the answer.
    The answer will be checked correct if its absolute or relative error doesn't exceed 106.
    Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if |ab|max(1,b)106.
     
    Sample Input
    4
    4
    4 0
    0 4
    4
    0 3
    3 0
    4
    0 2
    2 0
    4
    0 1
    1 0
     
    Sample Output
    5.6568543
    5.6568543
    5.8945030
    6.7359174
     
    Source
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  6119 6118 6117 6116 6115 
     
    以下转自:http://blog.csdn.net/kkkkahlua/article/details/77074409

    题意:

    圆心 O 坐标(0, 0), 给定两点 P, Q(不在圆外),满足 PO = QO,

    要在圆上找一点 D,使得 PD + QD 取到最小值。

    官方题解:

    做P点关于圆的反演点P',OPD与ODP'相似,相似比是|OP| : r。

    Q点同理。

    极小化PD+QD可以转化为极小化P'D+Q'D。

    当P'Q'与圆有交点时,答案为两点距离,否则最优值在中垂线上取到。

    时间复杂度 O(1)O(1)

    补充说明:

    反演:

    设在平面内给定一点O和常数k(k不等于零),对于平面内任意一点A,确定A′,使A′在直线OA上一点,并且有向线段OA与OA′满足OA·OA′=k,我们称这种变换是以O为的反演中心,以k为反演幂的反演变换,简称反演。——百度百科

    在这里,k 即为圆半径 r ^ 2,因此,相似就是显然的了。

    当 P'Q' 与圆有交点时:

    不妨设交点为 O',若 D 不为 O',则 P'D + Q'D >  P'Q'(三角形两边之和大于第三边);当且仅当 D 取 O' 时,P'Q + Q'D 取到最小值,即为 P'Q'。

    当 P'Q' 与圆无交点时:

    不妨将 P' 与 Q' 看成椭圆的两个焦点,当椭圆慢慢变大时,第一个碰到的圆上的点 D 即为使得 P'D + Q'D 最小的点;画个图就很显然了,第一个碰到的点即为 PQ 的中垂线与圆的交点。

    至于判断有 P'Q' 与圆有没有交点,就是圆心到直线的距离与半径比较,又因为此处 P'O=Q'O,所以只需要比较 P'Q' 的中点到圆心的距离和半径的大小。

    注意点:

    1. 注意 PO = QO = 0 的情况

    2. 尽量用比例而不是角度进行计算

     
    这题精度很是问题
    #include <iostream>
    #include<bits/stdc++.h>
    using namespace std;
    
    const double eps=1e-8;
    int t;
    double R,px,py,qx,qy;
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lf%lf%lf%lf%lf",&R,&px,&py,&qx,&qy);
            if (px==0 && py==0) {printf("%.7lf
    ",2*R);continue;}
            double r=sqrt(pow(px,2)+pow(py,2));
            double k=R*R/(r*r);  //不是相似比
            double ppx=px*k,ppy=py*k,qqx=qx*k,qqy=qy*k;
            //printf("%.2lf %.2lf
    ",ppx,ppy);
            double midx=(ppx+qqx)/2,midy=(ppy+qqy)/2;
            double dis=sqrt(pow(midx,2)+pow(midy,2) );
            //printf("%.7lf
    ",dis);
            if (dis<=R)
            {
               // double op2=sqrt(pow(ppx,2)+pow(ppy,2));
                printf("%.7lf
    ",sqrt(pow(ppx-qqx,2)+pow(ppy-qqy,2))*r/R);
    
            } else
            {
                double mx=midx/dis*R; double my=midy/dis*R;
                printf("%.7lf
    ",2*sqrt(pow(mx-px,2)+pow(my-py,2)) );
            }
        }
        return 0;
    }
  • 相关阅读:
    console.log添加样式及图片
    高效能Windows人士的N个习惯之一:启动篇
    视频播放插件JWPlayer的使用
    使用 Hexo 在 GitHub 上建立博客 · Utopia's Daily Note
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:嵌套列
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:偏移列
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:响应式的列重置
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:手机、平板电脑、台式电脑
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:中型和大型设备
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:堆叠的水平
  • 原文地址:https://www.cnblogs.com/stepping/p/7357134.html
Copyright © 2011-2022 走看看