#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
double x[1001],y[1001],z[1001];
bool book[1001];
int n,h,r;
bool flag;
double dist(double x1,double y1,double z1,double x2,double y2,double z2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));//求空间内两点距离公式
}
void dfs(int ball)
{
if(flag) return;
if(z[ball]+r>=h){//找到顶部出口
printf("Yes
");
flag=1;
return;
}
book[ball]=1;
for(int i=1;i<=n;i++){
if(flag) return;//避免重复去走,会TLE
if(dist(x[ball],y[ball],z[ball],x[i],y[i],z[i])<=r<<1&&!book[i]) dfs(i);//两洞中心距离小于2倍半径,则两洞相通
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%d%d%d",&n,&h,&r);
flag=0;
memset(book,0,sizeof(book));//初始化
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);
if(z[i]<=r) book[i]=1;//判断底部入口
}
for(int i=1;i<=n;i++){
if(flag) break;
else if(book[i]) dfs(i);
}
if(!flag) printf("No
");//如果没找到出口,则输出No
}
return 0;
}
NOIP2017提高组第二天第一题。其实就是简单的DFS,因为只要判断Yes和No,写好一点就可以了。总用时88ms。