已经快半夜了,嘛。。我的第一篇文章就写一道几何题目吧。
题目在这里http://community.topcoder.com/stat?c=problem_statement&pm=996&rd=4372 大意就是说,有n个城市,从标号第0个出发,最后又回来,最短距离是多少。因为最多只有9个,所以可以枚举所有可能组合,可以用<algorithm>里的next_permutation实现。当然,先要转化一下坐标。以地心为原点就有:
double x = sin(lng/180*PI)*cos(lat/180*PI)*radius;
double y = cos(lng/180*PI)*cos(lat/180*PI)*radius; double z = sin(lat/180*PI)*radius;
接下来呢?用点积
我开始把经度和纬度都弄成int了,WA了好长时间,我还是太菜了
# include <cstdio> # include <iostream> # include <vector> # include <sstream> # include <string> # include <algorithm> # include <cmath> # include <cfloat> # define PI acos(-1) using namespace std; vector<int> p; double x[20],y[20],z[20],d[20][20]; class Travel { public: int shortest(vector <string> cities, int radius) { int i,j,len = cities.size(); double ans = DBL_MAX,res,r = radius*1.0,la,lt; for (i=0;i<=len;++i) p.push_back(i%len); for (i=0;i<len;++i) { stringstream(cities[i])>>la>>lt; x[i] = cos((la/180)*PI)*cos((lt/180)*PI)*r; y[i] = cos((la/180)*PI)*sin((lt/180)*PI)*r; z[i] = sin((la/180)*PI)*r; } for (i=0;i<len;++i) for (j=i+1;j<len;++j) { double a = (x[i]*x[j]+y[i]*y[j]+z[i]*z[j])/(radius*radius); d[i][j] = d[j][i] = acos(a)*radius; } do { res = 0.0; for (i=1;i<=len;++i) res += d[p[i]][p[i-1]]; ans = min(ans,res); } while(next_permutation(p.begin()+1,p.end()-1)); return (int)(ans+0.5); } };