思路:
先看哪两个点能互通,再广搜寻找下一步,如果到达高度h就输出Yes,如果所有路径都找过都不能到达高度h就输出No。
#includeusing namespace std; long long t; long long n,h,r; long long x[1005],y[1005],z[1005]; long long maap[1005][1005]; long long book[1005]; long long flag=0; long long p;//用long long(数据范围大) int juli(long long a,long long b,long long c,long long d,long long e,long long f) { double sum1=sqrt((a-b)*(a-b)+(c-d)*(c-d)+(e-f)*(e-f));//判断两个点之间的距离 double bj=2*r;//double既不会爆有可以对付小数问题 if(sum1<=bj) return 1;//如果两个圆心的距离小于等于两个半径,说明这两个洞连着 else return 0; } int main() { cin>>t; queue<int> q;//初始化队列 while(t--)//t组数据 { flag=0;//判断有没有输出 while(!q.empty())q.pop(); memset(book,0,sizeof(book)); memset(maap,0,sizeof(maap));//初始化 //maap储存地图maap[i][j]储存i和j能不能相连 cin>>n>>h>>r;//输入 for(long long i=1;i<=n;i++) { cin>>x[i]>>y[i]>>z[i];//输入 if(z[i]+r>=h)book[i]=2;//判断第i个能不能到顶层,如果能book[i]=2 if(z[i]-r<=0)q.push(i);//如果这个点能到地面,就把它推入队列,准备广搜 } for(long long i=1;i<=n;i++) for(long long j=i;j<=n;j++) if(juli(x[i],x[j],y[i],y[j],z[i],z[j])==1) { maap[i][j]=1; maap[j][i]=1; }//判断i和j能否相连,储存在maap里 while(!q.empty()) { p=q.front();//取一个点开始广搜 q.pop();//搜过的点pop if(book[p]==2) { cout<<"Yes"<<endl; flag=1; break; }//如果这个点p可以到顶层,就输出yes,flag=1(代表已经输出过) if(book[p]!=1) { book[p]=1;//一个点不能重复走(实际可以,但是没有意义 for(long long k=1;k<=n;k++) if(maap[p][k]==1)//如果现在的点p可以到点k q.push(k);//把k推入队列,广搜 } } if(flag==0)//如果flag=0,说明没有输出过,也就是说不能到达顶层,输出-1; cout<<"No"<<endl; } return 0; }
请各位大佬斧正(反正我不认识斧正是什么意思)