空间里,分布着一些已知等球,还有$z=0$和$z=h$两个平面。规定相切或相交为“联通”,求两个平面的连通性。
找出和上、下平面联通的球,转换为求两个集合的连通性,宽搜搞一搞就欧了。
注意一点:判断“联通”的条件用平方后的整式,避开和精度打交道。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define IL inline using namespace std; typedef long long LL; const LL N=1e3; int T,n; LL h,r; struct Node{ LL x,y,z; }a[N+3]; bool v[N+3]; int q[N*4+3],hd,tl; IL LL sq(LL x){ return x*x; } IL bool acs(Node a,Node b){ return sq(r*2)>=sq(a.x-b.x) +sq(a.y-b.y) +sq(a.z-b.z); } int main(){ bool flag; int u; scanf("%d",&T); while(T--){ scanf("%d%lld%lld",&n,&h,&r); for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z); memset(v,0,n+1); hd=1; tl=0; for(int i=1;i<=n;i++) if(a[i].z<=r){ q[++tl]=i; v[i]=true; } flag=false; while(hd<=tl){ u=q[hd++]; if(a[u].z+r>=h){ flag=true; break; } for(int i=1;i<=n;i++) if(i!=u) if(acs(a[i],a[u])) if(!v[i]){ q[++tl]=i; v[i]=true; } } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }
5分钟的题目不能耗太多时间。祭奠我当年联赛这道题做的50分……
原文:https://www.cnblogs.com/Hansue/p/10990809.html