newoj 1120 水池

题目描述

有一个圆形的水池,它的圆心在坐标(0,0)点。水池中有一个桥连接,这个桥可以认为是平面上一条线段AB,并且A点和B点都在水池的边界上。

Roliy想从点F走到点G,F点和G点也都在水池的边界上。他有点胖所以不会游泳,所以他请你帮他写个程序告诉他从F点到G点的最小距离是多少。

输入描述

多组输入数据。

第一行包含一个整数R(1<=R<=100),表示水池的半径。

第二行包含8个实数XA,YA,XB,YB,XF,YF,XG,YG,表示点A,B,F,G的坐标。每个坐标满足|X^2+Y^2-R^2|<10^-8。

输出描述

对于每组测试数据输出答案,保留小数点后两位有效数字。

样例输入

1
0.7296270000 -0.6838453340 0.1980220000 -0.9801975758 0.3149110000 -0.9491212052 -0.7355960000 -0.6774204933
1
0.5173080000 0.8557992949 0.9360380000 -0.3518989380 0.3969010000 -0.9178614254 0.6165430000 -0.7873212363

样例输出

1.15
0.26

根据题目发现有两种方案:

一种是走桥:

一种是不走桥:

(这里说一下,一个圆大的那一段叫优弧,小的叫劣弧,题目要求最短的肯定求劣弧)

圆貌似是初中学的,已经忘完了,于是百度到

两点间的弦长(设为d):d=根号下[(x2-x1)²+(y2-y1)²]
圆心角θ=2arcsin(d/2r)
弧长L=rθ=2r·arcsin(d/2r)

套公式

xc=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//弦长
yxj1=asin(xc/(2*r))*2,yxj2=PI*2-yxj1;//圆心角
h1=r*yxj1,h2=r*yxj2;//弧长

桥的距离

//AB的距离
AB=sqrt((XA-XB)*(XA-XB)+(YA-YB)*(YA-YB));

全部代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<string>
#define ll long long
#define maxn 1000001
#define M(a,b) memset(a,b,sizeof(a))
#define inf 0x7fffffff
#define PI 3.1415926535898
using namespace std;
double min1(double a, double b){
    if( a<=b )
        return a;
    else
        return b;
}
double qxc(double x1,double y1,double x2,double y2,double r){
        double xc,yxj1,yxj2,h1,h2;
        //printf("%0.12lf %0.12lf %0.12lf %0.12lf\n",x1,y1,x2,y2);
        xc=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//弦长
        yxj1=asin(xc/(2*r))*2,yxj2=PI*2-yxj1;//圆心角
        h1=r*yxj1,h2=r*yxj2;//弧长
        //printf("%0.12lf %0.12lf %0.12lf %0.12lf %0.12lf\n",xc,yxj1,yxj2,h1,h2);
        return min1(h1,h2);
}
int main() {
    double r;
    double XA,YA,XB,YB,XF,YF,XG,YG;
    double FG,AB,ABFG;
    while(cin>>r){
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&XA,&YA,&XB,&YB,&XF,&YF,&XG,&YG);
        //FG的弧长
        FG=qxc(XF,YF,XG,YG,r);
        //AB的距离
        AB=sqrt((XA-XB)*(XA-XB)+(YA-YB)*(YA-YB));
        //ABFG的距离
        ABFG=min1(qxc(XA,YA,XF,YF,r),qxc(XB,YB,XF,YF,r))+min1(qxc(XB,YB,XG,YG,r),qxc(XA,YA,XG,YG,r));
        printf("%.2lf\n",min1(FG,AB+ABFG));
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值