uva 10553 Treasure Map

题意:给你海盗的航海路线,终点为宝藏地点,然后你的路线是按照海盗的航海路线偏移一定的角度去航行,求你在途中距离宝藏最近的是相距多少。

分析:先求出宝藏地点,然后求出宝藏地点到你航行的所有边的距离








#include <iostream>
#include<string>
#include<map>
#include<cmath>
#include<cstdio>
using namespace std;
#define N 1005
#define INF 0x79999999
double a[N];
string s[N];
double p_seg_dis(double x1,double y1,double x2,double y2,double x3,double y3);
double dis(double x1,double y1,double x2,double y2);
int main()
{
    int n;
     map<string, double>Map;
    Map.insert({ "N",0.0 });
    Map.insert({ "NbE",11.25 });
    Map.insert({ "NNE",22.5 });
    Map.insert({ "NEbN", 33.75 });
    Map.insert({ "NE",45 });
    Map.insert({ "NEbE",56.25 });
    Map.insert({ "ENE", 67.5 });
    Map.insert({ "EbN", 78.75 });
    Map.insert({ "E", 90 });
    Map.insert({ "EbS", 101.25 });
    Map.insert({ "ESE", 112.5 });
    Map.insert({ "SEbE", 123.75 });
    Map.insert({ "SE", 135 });
    Map.insert({ "SEbS", 146.25 });
    Map.insert({ "SSE", 157.5 });
    Map.insert({ "SbE",168.75 });
    Map.insert({ "S", 180 });
    Map.insert({ "SbW", 191.25 });
    Map.insert({ "SSW", 202.5 });
    Map.insert({ "SWbS", 213.75 });
    Map.insert({ "SW",225 });
    Map.insert({ "SWbW", 236.25 });
    Map.insert({ "WSW",247.5 });
    Map.insert({ "WbS",258.75 });
    Map.insert({ "W", 270 });
    Map.insert({ "WbN", 281.25 });
    Map.insert({ "WNW",292.5 });
    Map.insert({ "NWbW",303.75 });
    Map.insert({ "NW", 315 });
    Map.insert({ "NWbN",326.25 });
    Map.insert({ "NNW",337.5 });
    Map.insert({ "NbW", 348.75 });
    double l,x,y;//x,y为宝藏坐标
    while(~scanf("%d",&n)&n)
    {
        x=0;
        y=0;
        for(int i=0;i<n;i++){
                cin>>s[i];
        scanf("%lf",&a[i]);
        x+=a[i]*sin((Map[s[i]]/180)*acos(-1));
        y+=a[i]*cos(Map[s[i]]/180*acos(-1));
        }
       // cout<<acos(-1)<<endl;
       // cout<<x<<"   "<<y<<endl;
        double deviation;
        scanf("%lf",&deviation);
        double ans=INF;
        double x1=0,y1=0;
        for(int i=0;i<n;i++)
        {
            double tempx=x1;
            double tempy=y1;
            x1+=a[i]*sin((Map[s[i]]-deviation)/180*acos(-1));
            y1+=a[i]*cos((Map[s[i]]-deviation)/180*acos(-1));
            double aa=dis(x1,y1,x,y);
            double bb=dis(tempx,tempy,x,y);
            double cc=dis(x1,y1,tempx,tempy);
            if(aa*aa+cc*cc<bb*bb||bb*bb+cc*cc<aa*aa)
            {
                ans=min(ans,min(aa,bb));
            }
            else
            //cout<<p_seg_dis(tempx,tempy,x1,y1,x,y)<<endl;
            ans=min(ans,p_seg_dis(tempx,tempy,x1,y1,x,y));
          //  cout<<ans<<endl;
        }
        printf("%.2f\n",ans);
    }
    return 0;
}
//点到直线的距离
double p_seg_dis(double x1,double y1,double x2,double y2,double x3,double y3)
{
    double A,B,C,D;
     A = y1 - y2;
    B = x2 - x1;
    C = x1 * y2 - x2 * y1;
    D = fabs(A * x3 + B * y3 + C) / sqrt(A * A + B * B);
   return D;
}
//两点之间的最短距离
double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

,注意不是点到直线的距离,而是点到线段的距离。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值