NOIP 2017 奶酪

现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z = 0,奶酪的上表面为z = h

现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐 标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别 地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果 一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。

位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?


很显然的并查集水题,合并之后判断1和N是否在一个集合里

考场被卡了精度(当时还是太年轻)

下面给出代码:(原谅我当年难看的码风)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define unsigned long long long long
using namespace std;
inline long long read()
{
    long long x=0,f=1;
    char ch;
    do
    {
        ch=getchar();
        if(ch=='-') f=-1;
    }while(ch<'0'||ch>'9');
    do
    {
        x=x*10+(ch-'0');
        ch=getchar();
    }while(ch>='0'&&ch<='9');
    return x*f;
}
struct node
{
    long long a,b,c;
}s[10000];
bool cmp(const node a,const node b){ return a.c<b.c;}
long long f[10000];
long long check(long long v)
{
    if(f[v]==v) return v;
    else
    {
        f[v]=check(f[v]);
        return f[v];
    }
}
void marge(long long x,long long y)
{
    long long h1=check(x);
    long long h2=check(y);
    if(h1!=h2)
    {
        f[h2]=h1;
    }
    return ;
}
long long n,m,r;
long long cut(node h1,node h2)
{
    double hh=(h1.a-h2.a)*(h1.a-h2.a)+(h1.b-h2.b)*(h1.b-h2.b)+(h1.c-h2.c)*(h1.c-h2.c);
    hh=sqrt(hh);
    if(hh<=2*r) return 1;
    else return 0;
}
long long ans1[1010],ans2[1010];
int main()
{
    //freopen("cheese.in","r",stdin);
    //freopen("cheese.out","w",stdout);
    long long T;
    T=read();
    while(T--)
    {
        long long i,j;
        n=read();
        m=read();
        r=read();
        for(i=1;i<=n;i++) f[i]=i;
        for(i=1;i<=n;i++)
        {
            s[i].a=read();
            s[i].b=read();
            s[i].c=read();
        }
        sort(s+1,s+n+1,cmp);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++) if(cut(s[i],s[j])==1) marge(i,j);
        }
        long long cnt1=1,cnt2=1;
        for(i=1;i<=n;i++)
        {
            if(s[i].c<=r)
            {
                ans1[cnt1]=i;
                cnt1++;
            }
            if(s[i].c>=m-r)
            {
                ans2[cnt2]=i;
                cnt2++;
            }
        }
        int flag=0;
        for(i=1;i<cnt1;i++)
        {
            long long f1=check(ans1[i]);
            for(j=1;j<cnt2;j++)
            {
                long long f2=check(ans2[j]);
                if(f1==f2)
                {
                    printf("Yes\n");
                    flag=1;
                    break;
                }
            }
            if(flag==1) break;
        }
        if(flag==0) printf("No\n");
    }
    return 0;
}

 

posted @ 2018-11-04 14:55  Bruce--Wang  阅读(235)  评论(0编辑  收藏  举报