求助,70分wa678
查看原帖
求助,70分wa678
859027
EleanorSch楼主2023/6/23 14:33

如题

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll n , h , r ;
int f[1001];

struct poi{
	ll x;
	ll y;
	ll z;
};

//排序
bool cmp(struct poi a , struct poi b){
	if(a.z!=b.z)return a.z<b.z;
	if(a.y!=b.y)return a.y<b.y;
	return a.x<b.x;
}

//并查集
int find(int x){
	if(x!=f[x])f[x] = find(f[x]);
	return f[x];
}

//两个洞是否连接
bool qwq(struct poi a , struct poi b){
	return (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y)+(a.z - b.z)*(a.z - b.z) <= 4*r*r;
}


void solve(){
	
	//读入n,h,r
	cin >> n >> h >> r;
	
	//读入每个洞+并查集初始化
	struct poi a[1005];
	
	for(int i = 0 ; i < n ; i++){
		cin >> a[i].x >> a[i].y >> a[i].z;
		f[i] = i;
	}
	
	//排序
	sort(a,a+n,cmp);
	
	int min = 0 ;//与底部相接的洞数
	int max = 0 ;//与顶部相接的洞数
	
	//统计与底部相接的洞数
	for(int i = 0 ; i < n ; i++){
		if(a[i].z-r<=0)min++;
		else break;
	}
	
	//统计与顶部相接的洞数
	for(int i = n-1 ; i >= 0 ; i--){
		if(a[i].z + r >= h)max++;
		else break;
	}
	
	//如果不存在与顶部或底部相接的洞,直接输出No
	if(min==0||max==0){
		cout << "No" << '\n';
		return;
	}
	
	//逐个遍历
	for(int i = 1 ; i < n ; i++){
		
		//逐个比较
		for(int j = i-1 ; j >= 0 ; j--){
			
			if(a[j].z+r < a[i].z-r)break;//因为是按照z递增排序所以dz>2r的就不用看了
			
			//如果能连接,改变并查集
			if(qwq(a[i],a[j])){
				int tem1 = find(f[i]);
				int tem2 = find(f[j]);
				if(tem1!=tem2)f[i] = tem2;
			}
		}
	}
	
	//在和顶部相交的洞里找有没有和与在底部相交的洞相交的
	for(int i = 1 ; i <= max ; i++){
		if(find(f[n-i])<min){
			cout << "Yes" <<'\n';
			return;
		}
	}
	cout << "No" <<'\n';
	return;
}

int main(){
	
	//关闭同步流
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	int t = 1;
	cin >> t;
	while(t--)solve();
	return 0;
}
2023/6/23 14:33
加载中...