joj2487

本文介绍了一个关于寻找树木间最短且两侧景观数量相近路径的问题。通过输入不同树木坐标,算法找出符合特定条件的最短路径。核心在于处理浮点数计算时的精度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 2487: Central Avenue Road


ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s 65536K 743 169 Standard

There are a lot of trees in the park of Jilin University. We want to open up a road in this forest in a straight line from one tree to another. In order to view more scenery, the difference of both sides of the road is minimum (zero or one). If other tree is just on the road, it is not counted on both sides. Of course, we have a lot of ways to build this road. The best way is that the distance of two reference trees is shortest.

Input

The first line of each case is the number of trees N (2 <= N <=100). The next N lines have two integers that is the x and y coordinates of the i-th tree. The input file is terminated by N=0.

Output

For each case, output the distance of the two reference trees that the road obeys the above rules and the distance is shortest. Keep three digits after decimal point.

Sample Input

4
0 0
3 4
10 0
0 10
0

Sample Output

5.000

Problem Source: provided by skywind






















#include<stdio.h>
#include<math.h>
int main()
{
    double  a[102][3];
    int  n;
    double temp;
    while(scanf("%d",&n),n)
    {
        temp=0xffffffff;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&a[i][1],&a[i][2]);
        }
        for(int i=1;i<n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                double d=sqrt((a[i][1]-a[j][1])*(a[i][1]-a[j][1])+
                              (a[i][2]-a[j][2])*(a[i][2]-a[j][2]));
                int left=0;
                int right=0;
                if(d<temp)
                {
                    if(a[i][1]==a[j][1])
                    {
                        for(int t=1;t<=n;t++)
                        {
                            if(a[t][1]==a[i][1])continue;
                            if(a[t][1]>a[i][1])right++;
                            else if(a[t][1]<a[i][1]) left++;
                        }
                    }
                    else
                    {
                        double k=(a[i][2]-a[j][2])/(a[i][1]-a[j][1]);
                        double b=a[i][2]-a[i][1]*k;
                        for(int t=1;t<=n;t++)
                        {//注意精度
                            if(fabs(a[t][2]-(k*a[t][1]+b))<0.000002)continue;
                            if(a[t][2]>k*a[t][1]+b)right++;
                            else if(a[t][2]<k*a[t][1]+b)left++;
                        }
                    }
                    if(fabs(left-right)<=1)
                    temp=d;
                }
            }
        }
        printf("%.3lf\n",temp);
    }
    return 0;
}
//这个题虽然不难但是让我纠结了几个小时。首先是
//看了很久都没有理解题意。到后来才明白
//再就是精度没有处理好这里特别强调一下对于
//有关浮点数的计算一定要注意精度的选择,因为
//计算机对数的精确度是有要求的。不要把电脑真的当成了人脑。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值