洛谷 P3958 奶酪

读题,不难想到深搜
然后加上一个 vis 数组记录这个地方有没有来过,如果来过肯定就不再来了
同时,你还需要注意“坐标的 绝对值不超过 1,000,000,000”,记得算两点距离的时候要改成 long long 类型

#include<bits/stdc++.h>
#define reg register
#define ll long long
using namespace std;
int t;
struct node{
	int x;
	int y;
	int z;
}che[1007];
int vis[1007],Flag;
int n,h,r;
int Read();
double dis(int a,int b){
	return sqrt(((ll)che[a].x-(ll)che[b].x)*((ll)che[a].x-(ll)che[b].x)+((ll)che[a].y-(ll)che[b].y)*((ll)che[a].y-(ll)che[b].y)+((ll)che[a].z-(ll)che[b].z)*((ll)che[a].z-(ll)che[b].z));
}
void dfs(int k){
	if(che[k].z+r>=h){
		Flag=1;
		return;
	}
	for(reg int i=1;i<=n;++i)
		if(!vis[i]&&dis(k,i)<=2.0*r&&!Flag){//记得是2.0
			vis[i]=1;
			dfs(i);
			vis[i]=0;
		}
	return;
}
int main(){
	t=Read();
	while(t--){
		memset(vis,0,sizeof(vis));
		Flag=0;
		n=Read();h=Read();r=Read();
		for(reg int i=1;i<=n;++i){
			che[i].x=Read();
			che[i].y=Read();
			che[i].z=Read();
		}
		for(reg int i=1;i<=n;++i)
			if(!Flag&&(che[i].z-r)<=0){
				vis[i]=1;
				dfs(i);
				vis[i]=0;
			}
		Flag==1?cout<<"Yes\n":cout<<"No\n";
	}
	return 0;
}
int Read(){
	char ch=getchar();
	int res=0,flag=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-')flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return res*flag;
}

但是,有 30 分是会 TLE 的
那么,再进行思考:
一般我们写深搜时,总是要回溯,尤其是新学深搜的时候,老师一定会强调又强调

但是,这道题,真的有必要吗?

只要来过了,就一定会走下去,就一定有结果

那么,如果第一次就已经完成目标,还会有第二次吗?

不会。所以,无需回溯

所以,把上文代码中的

vis[i]=0;

全都去掉就行了

#include<bits/stdc++.h>
#define reg register
#define ll long long
using namespace std;
int t;
struct node{
	int x;
	int y;
	int z;
}che[1007];
int vis[1007],Flag;
int n,h,r;
int Read();
double dis(int a,int b){
	return sqrt(((ll)che[a].x-(ll)che[b].x)*((ll)che[a].x-(ll)che[b].x)+((ll)che[a].y-(ll)che[b].y)*((ll)che[a].y-(ll)che[b].y)+((ll)che[a].z-(ll)che[b].z)*((ll)che[a].z-(ll)che[b].z));
}
void dfs(int k){
	if(che[k].z+r>=h){
		Flag=1;
		return;
	}
	for(reg int i=1;i<=n;++i)
		if(!vis[i]&&dis(k,i)<=2.0*r&&!Flag){
			vis[i]=1;
			dfs(i);
		}
	return;
}
int main(){
	t=Read();
	while(t--){
		memset(vis,0,sizeof(vis));
		Flag=0;
		n=Read();h=Read();r=Read();
		for(reg int i=1;i<=n;++i){
			che[i].x=Read();
			che[i].y=Read();
			che[i].z=Read();
		}
		for(reg int i=1;i<=n;++i)
			if(!Flag&&(che[i].z-r)<=0){
				vis[i]=1;
				dfs(i);
			}
		Flag==1?cout<<"Yes\n":cout<<"No\n";
	}
	return 0;
}
int Read(){
	char ch=getchar();
	int res=0,flag=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-')flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return res*flag;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值