不知道为什么只有40分。好吧,是距离公式括号打错了。。。。。。。。。
距离其实可以不用开根号,直接比较平方大小。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#define ll long long
#define N 10001
using namespace std;
ll x[N],y[N],z[N],n,h,r;
int f[N],top,bottom,t;
int find(int x)
{
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
double dis(int a,int b)
{
return ((x[a] - x[b])*x[a] - x[b]) + (y[a] - y[b])*(y[a] - y[b]) + (z[a] - z[b])*(z[a] - z[b]);
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld",&n,&h,&r);
for(int i = 0;i <= n + 1;++i) f[i] = i;
top = n + 1;
bottom = 0;
for(int i = 1;i <= n;++i)
{
scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
if(z[i] + r >= h)
{
f[find(i)] = find(top);
}
if(z[i] - r <= 0)
{
f[find(i)] = find(bottom);
}
for(int j = 1;j < i;++j){
if(dis(i,j) <= 4*r*r)
{
f[find(i)] = find(j);
}
}
}
if(find(top) == find(bottom)) printf("Yes
");
else printf("No
");
}
return 0;
}
dalao的题解
#include<cstdio>
typedef long long ll;
const int N=1e3+10;
int set[N];
ll n,h,r;
struct node{
ll x,y,z;
}hole[N];//存点
void init()//初始化代表元全为自己
{
for(int i=0;i<=n+1;i++)
set[i]=i;
}
int findset(int x)//查找代表元
{
if(x==set[x])
return x;
else return set[x]=findset(set[x]);
}
void unionset(int x,int y)//并集
{
int fx=findset(x);
int fy=findset(y);
set[fy]=fx;
}
ll getdis(node a,node 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);
}
int main()
{
//freopen("in.txt","r",stdin);
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&n,&h,&r);//此处没写lld扣20
init();
int st=0,ed=n+1;//虚拟的起点终点
for(i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&hole[i].x,&hole[i].y,&hole[i].z);//此处没写lld再扣10
if(hole[i].z<=r)unionset(i,st);//合并起点和i
if(hole[i].z>=h-r)unionset(i,ed);//合并终点和i
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(getdis(hole[i],hole[j])<=(4*r*r))unionset(i,j);//将相通的点合并
if(findset(st)==findset(ed))printf("Yes
");//起点和终点在集合里说明连通
else printf("No
");
}
return 0;
}