zoukankan      html  css  js  c++  java
  • HDU 5295 Unstable 计算几何

    Unstable

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5295

    Description

    Rasen had lost in labyrinth for 20 years. In a normal day, he found a bright screen. There were 4 points labeled by ‘A’ , ‘B’ , ‘C’ , ‘D’, and rasen could drag these point. And two points ‘E’ , ‘F’ moved. Rasen found that ‘E’ is the middle point of ‘A’ and ‘B’, and ‘F’ is the middle point of ‘C’ and ‘D’. Near the screen there was a marble slab.There were a list of the distance of AB , BC , CD , DA and EF. Rasen also found that the distance of these edge of the points in screen showed at the same time he drop the points. He wanted to know what will happen if the distances in screen are same with the number in slab.

    Input

    The first line of input contains only one integer T(<=50000), the number of test cases.
    Each case contains five float number, indicating the distance of AB , BC , CD , DA , EF.(0<=distance<=10000)

    Output

    For each test, first print a line “Case #i:”(without quotes),with i implying the case number, then output the coordinates of A,B,C,D four points. Answer will be considered as correct if the length got from your output (the spj will use double to get the point, and the distance from two points will calculate in the way of sqrt((x1-x2)^2 +(y1-y2)^2) ) and the length given is less than 10-4.
    (It guarantees that there exists a solution. If there are many solutions, output any one of them.)

    Sample Input

    1
    1.000000 1.000000 1.000000 1.000000 1.000000

    Sample Output

    Case #1:
    0.000000 0.000000
    1.000000 0.000000
    1.000000 1.000000
    0.000000 1.000000

    Hint

    题意

    平面上有四个点A,B,C,D

    然后告诉你AB,BC,CD,DA长度,然后E是AB中点,F是CD中点,EF的长度你也知道。

    现在你需要构造一组解,使得满足要求。

    题解:

    随便画个四边形,然后延长AF到A‘,使得A’F=AF,做AB的平行线DG,使得DG=AB。

    然后连接A'C,A'B,A'G,CG

    显然的发现三角形DFA全等于三角形FCA',三角形AFE相似于三角形ABA'

    然后A‘就是以C点为圆心,AC为半径和B点为圆心,BA'为半径的圆相交的交点。

    知道A’之后,G点可以由CA'+CB得到。

    然后D点坐标就是以G为圆心,AB为半径,C为圆心,CD为半径的交点。

    然后A点就瞎搞就好了。

    然后就完了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    struct POINT
    {
     double x;
     double y;
     POINT(double a=0, double b=0) { x=a; y=b;} //constructor
    };
    void  c2point(POINT p1,double r1,POINT p2,double r2,POINT &rp1,POINT &rp2)
    {
        if(fabs(p1.x-p2.x)<1e-6&&fabs(p1.y-p2.y)<1e-6&&fabs(r1-r2)<1e-6)
        {
            rp1.x=p1.x;
            rp1.y=p1.y+r1;
            rp2.x=p1.x;
            rp2.y=p1.y-r1;
            return;
        }
         double a,b,r;
         a=p2.x-p1.x;
         b=p2.y-p1.y;
         r=(a*a+b*b+r1*r1-r2*r2)/2;
         if(fabs(a)<1e-6&&fabs(b)>1e-6)
         {
          rp1.x=rp2.x=r/b;
          double tmp = r1*r1-rp1.x*rp1.x;
          if(tmp<0)tmp=0;
          rp1.y=sqrt(tmp);
          rp2.y=-rp1.y;
         }
         else if(fabs(a)>1e-6&&fabs(b)<1e-6)
         {
          rp1.x=rp2.x=r/a;
          double tmp = r1*r1-rp1.x*rp2.x;
          if(tmp<0)tmp=0;
          rp1.y=sqrt(tmp);
          rp2.y=-rp1.y;
         }
         else if(fabs(a)>1e-6&&fabs(b)>1e-6)
         {
          double delta;
          delta=b*b*r*r-(a*a+b*b)*(r*r-r1*r1*a*a);
          if(delta<0)delta=0;
          rp1.y=(b*r+sqrt(delta))/(a*a+b*b);
          rp2.y=(b*r-sqrt(delta))/(a*a+b*b);
          rp1.x=(r-b*rp1.y)/a;
          rp2.x=(r-b*rp2.y)/a;
         }
    
         rp1.x+=p1.x;
         rp1.y+=p1.y;
         rp2.x+=p1.x;
         rp2.y+=p1.y;
    }
    void solve(int Cas)
    {
        double ab,bc,cd,da,ef;
        scanf("%lf %lf %lf %lf %lf",&ab,&bc,&cd,&da,&ef);
        POINT A,B,C,D,E,F,G,A1;
        C.x=0,C.y=0;
        B.x=bc,B.y=0;
        POINT tmp1,tmp2;
    
        c2point(C,da,B,2*ef,tmp1,tmp2);
    
        A1=tmp1;
        G.x=A1.x+B.x,G.y=A1.y+B.y;
    
        c2point(C,cd,G,ab,tmp1,tmp2);
        D=tmp1;
    
        A.x=D.x+C.x-A1.x;
        A.y=D.y+C.y-A1.y;
    
        printf("Case #%d:
    ",Cas);
        printf("%.12f %.12f
    ",A.x,A.y);
        printf("%.12f %.12f
    ",B.x,B.y);
        printf("%.12f %.12f
    ",C.x,C.y);
        printf("%.12f %.12f
    ",D.x,D.y);
    }
    int main()
    {
        int t;scanf("%d",&t);
        for(int i=1;i<=t;i++)solve(i);
        return 0;
    }
  • 相关阅读:
    探索c#之一致性Hash详解
    Redis系列(三)-Redis发布订阅及客户端编程
    Redis系列(二)-Hredis客户端设计及开源
    关于电脑操作一些高效的方法工具
    探索c#之递归APS和CPS
    探索C#之系列目录导航
    探索c#之不可变数据类型
    SOA相关资料整理分享
    探索c#之尾递归编译器优化
    探索c#之函数创建和闭包
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5280711.html
Copyright © 2011-2022 走看看