[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
");
			break;
		}
		if(!fl)printf("No
");
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/clockwhite/p/13493484.html