写代码是一种艺术,甚于蒙娜丽莎的微笑!

不拼搏,枉少年!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
题目描述:

    In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to form a picture of the Liberty Bell. Alas, one of the freckles turns out to be a scar, so his Ripley's engagement falls through. 
    Consider Dick's back to be a plane with freckles at various (x,y) locations. Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used. Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines. When Richie is done there must be a sequence of connected lines from any freckle to any other freckle. 

输入:

    The first line contains 0 < n <= 100, the number of freckles on Dick's back. For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle.

输出:

    Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles.

样例输入:
3
1.0 1.0
2.0 2.0
2.0 4.0
样例输出:
3.41

英文不好的话,阅读本题实在有些难度,里面出现的关键词如freckles等都是六级词汇。呵呵了......
下面解释一下该题的意思,大意就是在二维坐标系内,知道一些点的坐标,用线将这些点连通,保持线的总长度最短。哈哈这还是最小生成树问题啊,换汤不换药啊!
好,不多说,上菜了!

#include <iostream>
#include <algorithm>
#include <iomanip>

using namespace std;
int visited[101];

struct Edge{
    int vertex1;
    int vertex2;
    double cost;
};

struct Point{
    double x;
    double y;
    double computeDistance(Point A)
    {
        double tmp = (x - A.x)*(x - A.x) + (y - A.y)*(y - A.y);
        return sqrt(tmp);
    }
}points[101];
int cmp(const void *a, const void *b)
{
    Edge *e1 = (Edge*) a;
    Edge *e2 = (Edge*) b;
    return e1->cost - e2->cost;
}

Edge edges[5000];
int main()
{
    int n;
    double costs;
    while (cin >> n && n != 0)
    {
        int size = 0;
        costs = 0;
        for (int i = 0; i <= n; i++)
            visited[i] = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> points[i].x >> points[i].y;
        }
        for (int i = 1; i <= n; i++)
        {
            for (int j = i + 1; j <= n; j++)
            {
                edges[size].vertex1 = i;
                edges[size].vertex2 = j;
                edges[size].cost = points[i].computeDistance(points[j]);
                size++;
            }
        }
        
        qsort(edges, size, sizeof(Edge), cmp);

        for (int j = 0; j < size; j++)
        {
            if (visited[edges[j].vertex1] == 0 || visited[edges[j].vertex2] == 0)
            {
                costs += edges[j].cost;
                visited[edges[j].vertex1] = 1;
                visited[edges[j].vertex2] = 1;
            }
        }
        cout <<fixed << setprecision(2);
        cout << costs << endl;
    }
    
    return 0;
}

关于用cout控制小数位数的输出,可以参考前面的文章http://www.cnblogs.com/tgycoder/p/5010463.htmlC++输入输出流格式控制

再给个例子回顾一下:

#include <iostream>
#include <iomanip>

using namespace std;

int main(void)

{

    const double value = 12.3456789;

    cout << value << endl; // 默认以6精度,所以输出为 12.3457

    cout << setprecision(4) << value << endl; // 改成4精度,所以输出为12.35

    cout << setprecision(8) << value << endl; // 改成8精度,所以输出为12.345679

    cout << fixed << setprecision(4) << value << endl; // 加了fixed意味着是固定点方式显示,所以这里的精度指的是小数位,输出为12.3457

    cout << value << endl; // fixed和setprecision的作用还在,依然显示12.3457

    cout.unsetf(ios::fixed); // 去掉了fixed,所以精度恢复成整个数值的有效位数,显示为12.35

    cout << value << endl;

    cout.precision(6); // 恢复成原来的样子,输出为12.3457

    cout << value << endl;
}

 

posted on 2015-12-03 22:29  RunningSnail  阅读(537)  评论(0编辑  收藏  举报