luogu 3958 奶酪

题目: 题目链接 注释:牛客数据水了 现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中,奶酪的下表面为 z = 0,奶酪的上表面为 z = h。

现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。

位于奶酪下表面的 Jerry 想知道,在不破坏奶酪的情况下,能否利用已有的空洞跑 到奶酪的上表面去? 1、用并查集来解决 将上表面和下表面看做0和n+1,从1到n连接各个点, 如果洞和上表面相交或者相切,则连接,如果和下表面相切或者相交,那么连接,最后检查上表面和下表面是不是同一个祖先即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll n,h,r;
struct ty{
	ll x;
	ll y;
	ll z;
};
ty a[1005];
int pre[1005];
int find(int x){
	int r=x;
	while(r!=pre[r]){
		r=pre[r];
	}
	int j=x,temp;
	while(pre[j]!=r){
		temp=pre[j];
		pre[j]=r;
		j=temp;
	}
	return r;
}
void merge(int x,int y){
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy){
		pre[fx]=fy;
	}
	return ;
}
int visited[1005];
bool check(int i,int j){
	if((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)+(a[i].z-a[j].z)*(a[i].z-a[j].z)<=4*r*r) return true;
	return false;
}
int main(){
	memset(visited,0,sizeof(visited));
	cin>>t;
	while(t--){
		cin>>n>>h>>r;
		for(int i=0;i<=n+1;i++) pre[i]=i;
		for(int i=1;i<=n;i++){
			cin>>a[i].x>>a[i].y>>a[i].z;
			if(a[i].z<=r) merge(0,i);
			if(a[i].z>=h-r) merge(n+1,i);
		}
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				if(check(i,j)){
					merge(i,j);
				}
			}
		}
		if(find(0)==find(n+1)) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}

2、用dfs来解决 找到一个与下表面相交或者相切的点,然后开始从这个点开始遍历各个点,如果出现了与上表面相切或者相交的点,那么就输出Yes,否则输出No。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll n,h,r;
struct ty{
	ll x;
	ll y;
	ll z;
};
ty a[1005];
int visited[1005];
vector<int > g;
int flag=0;
bool check(int i,int j){
	if((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)+(a[i].z-a[j].z)*(a[i].z-a[j].z)<=4*r*r) return true;
	return false;
}
void dfs(int x){
	if(flag==1) return ;
	if(a[x].z>=h-r){
		flag=1;
		return ;
	}
	visited[x]=1;
	for(int i=1;i<=n;i++){
		if(!visited[i]&&check(x,i)){
			dfs(i);
		}
	}
	return ;
}
int main(){
	cin>>t;
	while(t--){
		g.clear();//记得清除每一次的vector 
		flag=0;
		memset(visited,0,sizeof(visited));
		cin>>n>>h>>r;
		for(int i=1;i<=n;i++){
			cin>>a[i].x>>a[i].y>>a[i].z;
			if(a[i].z<=r) g.push_back(i);//将与小表面相邻的点存入vector中 
		}
		int len=g.size();
		for(int i=0;i<len;i++){
        //每一次dfs的visited数组没有更新为0,因为可以到达上层的路线不会和之前无法到达的路线连通,这样做反而对DFS进行了剪枝,使DFS的搜索次数减少
			if(flag==1) break;
			if(!visited[g[i]]){
				dfs(g[i]);
			}
		}  
		if(flag) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}
全部评论

相关推荐

就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务