现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z = 0,奶酪的上表面为z = h。
现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐 标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别 地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果 一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?
#include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #define unsigned long long long long using namespace std; inline long long read() { long long x=0,f=1; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=x*10+(ch-'0'); ch=getchar(); }while(ch>='0'&&ch<='9'); return x*f; } struct node { long long a,b,c; }s[10000]; bool cmp(const node a,const node b){ return a.c<b.c;} long long f[10000]; long long check(long long v) { if(f[v]==v) return v; else { f[v]=check(f[v]); return f[v]; } } void marge(long long x,long long y) { long long h1=check(x); long long h2=check(y); if(h1!=h2) { f[h2]=h1; } return ; } long long n,m,r; long long cut(node h1,node h2) { double hh=(h1.a-h2.a)*(h1.a-h2.a)+(h1.b-h2.b)*(h1.b-h2.b)+(h1.c-h2.c)*(h1.c-h2.c); hh=sqrt(hh); if(hh<=2*r) return 1; else return 0; } long long ans1[1010],ans2[1010]; int main() { //freopen("cheese.in","r",stdin); //freopen("cheese.out","w",stdout); long long T; T=read(); while(T--) { long long i,j; n=read(); m=read(); r=read(); for(i=1;i<=n;i++) f[i]=i; for(i=1;i<=n;i++) { s[i].a=read(); s[i].b=read(); s[i].c=read(); } sort(s+1,s+n+1,cmp); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) if(cut(s[i],s[j])==1) marge(i,j); } long long cnt1=1,cnt2=1; for(i=1;i<=n;i++) { if(s[i].c<=r) { ans1[cnt1]=i; cnt1++; } if(s[i].c>=m-r) { ans2[cnt2]=i; cnt2++; } } int flag=0; for(i=1;i<cnt1;i++) { long long f1=check(ans1[i]); for(j=1;j<cnt2;j++) { long long f2=check(ans2[j]); if(f1==f2) { printf("Yes "); flag=1; break; } } if(flag==1) break; } if(flag==0) printf("No "); } return 0; }