1 solutions

  • 1
    @ 2024-1-5 10:16:51

    题意:有一个奶酪,奶酪里面有洞,问你可不可以从底部钻进去,然后从顶部钻出来

    分析:并查集,能联通的洞为同一个集合,如果洞能连底,那么这个集合down值+1,同理,能连顶部就up+1,如果一个集合up和down都大于1,那么这个集合就可以联通上下。解题的时候暴力求两个洞是否联通,和能否到顶/底就可以了。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+12;
    int t,n,r,h;
    struct {
      int up,down,fa;
    }p[N];
    struct node{
      long long x,y,z;
    }l[N];
    int f(int x,int down,int up)
    {
      if( x==p[x].fa ) {
          p[x].down=max(down,p[x].down);
          p[x].up=max(up,p[x].up);
          return x;
      }
        return p[x].fa=f( p[x].fa,down,up );
    
    }
    long long g(long long x)
    {
      return x*x;
    }
    int to(long long x,long long y,long long z,long long x2,long long y2,long long z2)
    {
      //cout<<sqrt( g(x-x2) + g(y-y2) + g(z-z2))<<endl;
      if( 2*r>=sqrt( g(x-x2) + g(y-y2) + g(z-z2) ) ) return 1;
      return 0;
    }
    
    int main(){
      cin>>t;
      while(t--)
      {
        cin>>n>>h>>r;
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
          cin>>l[i].x>>l[i].y>>l[i].z;
          p[i].down=(l[i].z<=r);
          p[i].up=( h-l[i].z<=r );
          p[i].fa=i;
          if( p[i].down and p[i].up ) cnt++;
        }
        for(int i=1;i<=n;i++)
        {
          for(int j=i+1;j<=n;j++)
          {
            if( to( l[i].x,l[i].y,l[i].z,  l[j].x,l[j].y,l[j].z ) )
            {
              int a=f( i,p[i].down,p[i].up ),b=f( j,p[j].down,p[j].up );
              if( a==b ) continue;
              p[b].fa=a;
              p[a].down=max( p[a].down,p[b].down );
              p[a].up =max( p[a].up,p[b].up );
              if( p[a].down and p[a].up ) cnt++;
            }
          }
        }
        if(cnt) cout<<"Yes\n";
        else cout<<"No\n";
      }
    
    
    
    
    }
    
    • 1

    Information

    ID
    11211
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    2
    Accepted
    2
    Uploaded By