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;
}