5476. 【NOIP2017提高组正式赛】奶酪

题目描述

现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中,奶酪的下表面为z = 0,奶酪的上表面为z = h。
现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐标。两相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个,特别地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑到奶酪的上表面去?
这里写图片描述

题目分析

此题非常水,递归即可。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
ll x[1100],y[1100],z[1100];
bool bk[1100],bz;int n;ll h,r;
int abs(int x)
{
    if(x<0) return -x;
    else return x;
}
bool pd(int a,int b)
{
    ll temp=abs(x[a]-x[b])*abs(x[a]-x[b]);
    temp+=abs(y[a]-y[b])*abs(y[a]-y[b]);
    temp+=abs(z[a]-z[b])*abs(z[a]-z[b]);
    if(temp<=4*r*r) return true;
    else return false;
}
void dfs(int k)
{
    bk[k]=false;
    if((h-z[k])<=r)
    {
        bz=true;
        return ;
    }
    for(int i=1;i<=n;i++)
    {
        if(bk[i]==true&&pd(k,i)==true)
        {
            dfs(i);
            if(bz==true)
            {
                return ;
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%lld%lld",&n,&h,&r);
        memset(bk,true,sizeof(bk));bz=false;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(bk[i]==true&&z[i]<=r)
            {
                dfs(i);
                if(bz==true)
                {
                    break;
                }
            }
        }
        if(bz==true) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
展开阅读全文

没有更多推荐了,返回首页