一道简单的几何题

已经快半夜了,嘛。。我的第一篇文章就写一道几何题目吧。

题目在这里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);
    }
};



原文地址:https://www.cnblogs.com/1carus/p/3315931.html