1. 程式人生 > 實用技巧 >[Noip2017]乳酪

[Noip2017]乳酪

[Noip2017]乳酪

一.前言

​ 做不起其他原題了qwq……題目連結

二.思路

​ 就,這題還蠻水的拉,由於不能在空洞中施展空間(?)跳躍魔法,就必須從某一個與底面相連的球一口氣走到另一個與頂面相連的球處。並查集一下,將相通的空間放到一個集合中,然後記錄一下是否和頂部底部相連就好。(話說相切也行就比較魔幻?)

三.CODE

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<fstream>
#include<cmath>
using namespace std;
int read(){
	char ch=getchar();
	int res=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
	return res*f;
}
int t,n,h,r;
int x[1005],y[1005],z[1005],f[1005];
bool is[1005];
inline int get(int x){
	if(f[x]==x)return x;
	f[x]=get(f[x]);
	is[x]=is[f[x]];
	return f[x];
}
inline double dis(int i,int j){
	return sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+1.0*(y[i]-y[j])*(y[i]-y[j])
	+1.0*(z[i]-z[j])*(z[i]-z[j]));
}
int main(){
	t=read();
	while(t--){
		n=read();h=read();r=read();
		for(int i=1;i<=n;++i){
			f[i]=i;is[i]=0;
			x[i]=read();y[i]=read();z[i]=read();
			is[i]=((h-z[i])<=r);
			for(int j=i-1,fj,fi;j>=1;--j){
				fi=get(i);fj=get(j);
				if(fi!=fj&&dis(j,i)<=2.0*r){
					//cout<<"wdnmd"<<endl;
					f[fi]=fj;
					is[fj]=(is[fi]||is[fj]);	
				}
			}
		}
		bool fl=0;
		for(int i=1;i<=n;++i)
		if(z[i]<=r&&is[get(i)]){
			fl=1;
			printf("Yes\n");
			break;
		}
		if(!fl)printf("No\n");
	}
	return 0;
}