zoukankan      html  css  js  c++  java
  • POJ2031Building a Space Station

    http://poj.org/problem?id=2031

    题意:你是空间站的一员,太空里有很多球形且体积不一的“小房间”,房间可能相距不近,也可能是接触或者甚至是重叠关系,所有的房间都必须相连,这样的话宇航员才能从这个房间走到另一个房间,而宇航员从一个房间走到另一个房间,只要满足三个条件中的一个即可:1两个房间是接触的,2两个房间是重叠的,3两个房间之间有走廊相连。也因此若是没有接触的两个小房间就要有走廊连接,忽略走廊的宽度,花费与长度成正比,所以当然是花费越少越好,而球与球之间的距离只接触到两球的表面即可,因为两球的表面相距最近,因此你的工作就是算给出的几个小房间中要达到相连的状态需花费的最小钱数是多少

    思路:要求两个房间之间必须要有相连的走廊,所以就是最小生成树的思想,只要再考虑一下是不是接触或重叠就可以了

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    
    using namespace std ;
    
    const double eps=1e-8 ;
    const int INF = 1<<28;
    
    struct point
    {
        double x,y,z,w ;
        point() {}
        point(double a,double b,double c,double d):x(a),y(b),z(c),w(d) {}
    };
    
    inline double sqrt1(double a)//函数被调用的次数多了就比较浪费时间,所以可以定义成内置函数
    {
        return a*a;
    }
    
    double dis(const point &a,const point &b)//求两点间距离
    {
        return sqrt(sqrt1(a.x-b.x)+sqrt1(a.y-b.y)+sqrt1(a.z-b.z));
    }
    
    double low[1000] ;
    double dist[110][110],ans ;
    bool vis[1000] ;
    int n ;
    
    int prim()
    {
        ans = 0 ;
        int i,j,flag;
        double minn ;
        for(i = 1 ; i <= n ; i++)
        {
            low[i] = INF ;
            vis[i] = false ;
        }
        low[1] = 0 ;
        for(i = 1 ; i <= n ; i++)
        {
            minn = INF ;
            flag = 0 ;
            for(j = 1 ; j <= n ; j++)
            {
                if(minn > low[j]&&!vis[j])
                {
                    minn = low[j] ;
                    flag = j ;
                }
            }
            if(minn >= INF)
                return false ;
            ans += minn ;
            vis[flag] = true ;
            for(j = 1 ; j <= n ; j++)
            {
                if(!vis[j]&&low[j]>dist[flag][j])
                    low[j] = dist[flag][j] ;
            }
        }
        return true ;
    }
    
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            point a[1000];
            memset(dist,0,sizeof(dist));
            for(int i=1; i<=n; i++)
                scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z,&a[i].w);
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    if(dis(a[i],a[j])-a[i].w-a[j].w<=0)//两球间最短距离为两球球心距离再减去两球的半径
                        dist[i][j]=0;
                    else if(dis(a[i],a[j])-a[i].w-a[j].w>eps)
                        dist[i][j]=dis(a[i],a[j])-a[i].w-a[j].w;
                }
            }
            prim();
            printf("%.3lf
    ",ans);
        }
        return 0;
    }
    View Code

    特别郁闷的是明明是同一个代码,一开始交是0ms后来交就是16ms。。。。。

  • 相关阅读:
    Linux虚拟机突然不能上网了
    项目经验不丰富、技术不突出的程序员怎么打动面试官?
    10分钟看懂!基于Zookeeper的分布式锁
    BATJ等大厂最全经典面试题分享
    分享30道Redis面试题,面试官能问到的我都找到了
    一个六年Java程序员的从业总结:比起掉发,我更怕掉队
    我是这样手写 Spring 的(麻雀虽小五脏俱全)
    自述:为什么一部分大公司还在采用过时的技术,作为技术人而言该去大公司还是小公司
    Java精选面试题之Spring Boot 三十三问
    Java程序员秋招面经大合集(BAT美团网易小米华为中兴等)
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3400578.html
Copyright © 2011-2022 走看看