jzoj4383. 【GDOI2016模拟3.11】小行星

题目描述

这里写图片描述

15%

贪心,考虑前2000整数秒,每次构出MST再判断
话说我考试是只写了二维欧几里得距离居然没挂

25%

因为有一个数据点是方向速度相同,所以根据物体的相对运动可以得出所有的行星是相对静止的
于是printf(“1\n”)

加上贪心就有25%

100%

题目中的时间可能不是整数(考试是居然没想到)
假设当前的MST方案为s,则MST为s的时间一定是一个时间段[l,r]
显然不可能有多段时间(感性理解
于是考虑二分往后找,每次找一个不同与当前MST的方案

由于是完全图,所以prim比Kruskal要快
原来我之前一直打的都是N^3的prim

code

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define Len 2000
#define e 3e-5
using namespace std;

int fa[51];
double x[51];
double y[51];
double z[51];
double x2[51];
double y2[51];
double z2[51];
double b[51];
int c[51];
bool bz[51][51];
int n,i,j,k,T,t,ans;
double l,r,mid;

double dis(int i,int j,double t)
{
    return sqrt((x[i]+(x2[i]-x2[j])*t-x[j])*(x[i]+(x2[i]-x2[j])*t-x[j])+(y[i]+(y2[i]-y2[j])*t-y[j])*(y[i]+(y2[i]-y2[j])*t-y[j])+(z[i]+(z2[i]-z2[j])*t-z[j])*(z[i]+(z2[i]-z2[j])*t-z[j]));
}

bool work(double t,bool S)
{
    int i,j,k,l;
    double s;

    c[1]=0;
    fo(i,2,n)
    {
        b[i]=dis(1,i,t);
        c[i]=1;
    }

    fo(i,2,n)
    {
        s=23333333333;

        fo(j,1,n)
        if (c[j] && s>b[j])
        {
            s=b[j];
            k=j;
        }
        if (S)
        bz[c[k]][k]=1,bz[k][c[k]]=1;
        else
        if (!bz[c[k]][k])
        return 0;

        c[k]=0;

        fo(j,1,n)
        if (c[j])
        {
            s=dis(j,k,t);

            if (s<b[j])
            {
                b[j]=s;
                c[j]=k;
            }
        }
    }

    return 1;
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        T++;

        fo(i,1,n)
        scanf("%lf%lf%lf%lf%lf%lf",&x[i],&y[i],&z[i],&x2[i],&y2[i],&z2[i]),fa[i]=i;

        ans=0;
        l=0;
        while (l<Len)
        {
            l+=e;
            r=Len;

            memset(bz,0,sizeof(bz));
            work(l,1);

            while (r-l>e)
            {
                mid=(l+r)/2.0;

                if (work(mid,0))
                l=mid;
                else
                r=mid;
            }

            if (l<Len)
            ans++;
        }

        printf("Case %d: %d\n",T,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/gmh77/article/details/81091770