题目描述
现有一块大奶酪,它的高度为 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;
}