uva 10553 Treasure Map (藏宝图)

Problem E: Treasure Map

You have come into possession of a pirate map that gives a series of steps to get from your landing place on a desert isle to  the spot marked X  where the treasure is located. Each step consists of a compass heading and a number of paces.

After spending most of your savings chartering a boat, you arrive at the island and, with the help of your portable GPS receiver, duly execute the instructions on the map. Alas, no treasure! On your return home you are astonished to learn that the pirates had no knowledge of GPS and used a magnetic compass to create the map. The pirates were unaware that their compass pointed to magnetic northrather than true north. The relative angle between magnetic north and true north varies depending where you are on the planet, but you are able to determine that on this particular desert isle, magnetic north is d degrees from true north. How close were you to the spot marked X at any moment while following the map?

There are several test cases. Each test case begins with n <= 1000, the number of steps in the map. n lines follow; each consists of one of the 32 named compass points shown at right followed by a number of paces. The last line is a number giving the angle between magnetic north and true north, in degrees. A positive number indicates that magnetic north is to the east of true north; a negative indicates that it is to the west. The magnitude of this angle will not exceed 90 degrees. A line containing 0 follows the input for the last case.

For each test case, output a single number, rounded to two decimal places, giving the least distance (in paces) that separated you from the treasure at any point while you were following the map.

Note: We use combinations of the letters N,E,S,W,b to abbreviate the names of the compass points. For example, NEbE stands for north-east by east. The 32 points are equally spaced about the compass. Clockwise, they are: N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE SEbE SE SEbS SSE SbE S SbW SSW SWbS SW SWbW WSW WbS W WbN WNW NWbW NW NWbN NNW NbW.

Sample Input

2
NbE 10
EbS 10
90.00
2
NbE 10
EbS 10
-90.00
0

Output for Sample Input

14.14
10.00



题目大意:有一个藏宝地点是以海盗的方向标记的,但是你的罗盘与海盗的路线有误差是恒定的角度,问你按照藏宝图走过程中与藏宝点 最少距离多少?

解题思路:很简单算出宝藏的实际地点,然后计算 你的 航线算出航线 过程中与 藏宝地点的最短距离(即藏宝点到所有线段的最小距离)即可。

注意点,wa了很多次,结果是因为定义的圆周率pai精度不高,定义为acos(-1),就ok了




解题 代码 :


#include <iostream>
#include <string>
#include <cstdio>
#include <map>
#include <cmath>
#include <vector>
using namespace std;

const double pai=acos(-1);//此处为坑点,如果pai精度不高(如3.14159)就可能wa
const string st[]={"N","NbE","NNE","NEbN","NE","NEbE","ENE","EbN","E","EbS","ESE",
"SEbE","SE","SEbS","SSE","SbE","S","SbW","SSW","SWbS","SW","SWbW","WSW","WbS","W","WbN",
"WNW","NWbW","NW","NWbN","NNW","NbW"};

struct point{
	double x,y;
	point(double x0=0,double y0=0){x=x0;y=y0;}
	double getdis(point p){
		return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
	}
};

struct dir{//方向
	double a,dis;//a为角度,dis为偏移距离
	dir(double a0=0,double dis0=0){a=a0;dis=dis0;}
};

double dchen(point p0,point p1,point p2){//p0p1点乘 p0p2;
	return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}

struct line{
	point a,b;
	line(point a0,point b0){a=a0;b=b0;}
	double getdis(point p){//点到线段的最小距离
		if(dchen(a,p,b)<0 || dchen(b,p,a)<0) return min(p.getdis(a),p.getdis(b));
		else{
			double a0,b0,c0;
			a0=a.y-b.y;
			b0=b.x-a.x;
			c0=a.x*b.y-b.x*a.y;
			return fabs(a0*p.x+b0*p.y+c0)/sqrt(a0*a0+b0*b0);
		}
	}
};

map <string,double> mp;
vector <dir> v;
int n;
double off;

void ini(){
	for(int i=0;i<32;i++){
		mp[st[i]]=pai*double(i)/double(16);
	}
}

void initial(){
	v.clear();
}

void input(){
	string st0;
	double dis0;
    for(int i=0;i<n;i++){
    	cin>>st0>>dis0;
    	v.push_back(dir(mp[st0],dis0));
    }
    cin>>off;
}

void computing(){
	point d(0,0),t(0,0),pre;
	for(int i=0;i<n;i++){//算出宝藏的真正点 终点d
		d.x+=cos(v[i].a)*v[i].dis;
		d.y+=sin(v[i].a)*v[i].dis;
	}
	double ans=d.getdis(t);
	for(int i=0;i<n;i++){//算出实际寻宝每次的路线为 line l(pre,t);
		pre=t;
		t.x+=cos(v[i].a-off*pai/double(180))*v[i].dis;
		t.y+=sin(v[i].a-off*pai/double(180))*v[i].dis;
		line l(pre,t);
		ans=min(ans,l.getdis(d));//求出路线 line l 距离宝藏点d距离
	}
	printf("%.2lf\n",ans);
}

int main(){
	ini();
    while(scanf("%d",&n)!=EOF && n!=0){
        initial();
        input();
        computing();
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炒饭君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值