试题 算法训练 小生物的逃逸
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
空间中有n个球,这些球不相交也不相切。有m个可以视为质点的小生物,可能在某些球内,也可能在所有球之外,但不会在球面上。问这些生物从原来的地方逃逸到所有球外面的空间,至少要经过多少层球面。
输入格式
第一行两个数n、m:表示球的数量和小生物的数量;
接下来n行每行四个整数Xi、Yi、Zi和Ri:表示一个球的三维坐标和半径;
接下来m行每行三个整数Xi、Yi、Zi:表示一个生物的坐标。
输出格式
一行m个数:表示每个小生物逃逸时至少经过的球面数。
样例输入
2 2
0 0 0 2
0 0 0 4
0 0 1
0 0 3
样例输出
2 1
数据规模和约定
1<=n、m<=100,|Xi|、|Yi|、|Zi|<=10000,1<=Ri<=10000;
数据保证所有球严格不接触,小生物都不在球面上。
算法分析
这道题的关键就是要找出每个质点被多少个小球包住,那么也就是对质点到每个球的圆心的距离d的判断,假如d的值小于球体的半径r那么这个质点一定球体的内部。,即我们需要求的结果
主要方法实现
我们可以定义一个球体类Ball,实现一个构造方法和距离方法(任一点到该球的圆心的距离)。
public static class Ball{
int x,y,z,r;
public Ball(int x,int y,int z,int r){
this.x=x;
this.y=y;
this.z=z;
this.r=r;
}
public double distance(int x ,int y,int z){
double distance=Math.sqrt(Math.pow((this.x-x),2)+Math.pow((this.y-y),2)+Math.pow((this.z-z),2));
return distance;
}
完整代码
主程序中,循环求每个小生物到每个球的距离即可。完整代码如下
package AlgorithmTrainning;
import java.util.*;
public class 小生物的逃逸 {
public static class Ball{
int x,y,z,r;
public Ball(int x,int y,int z,int r){
this.x=x;
this.y=y;
this.z=z;
this.r=r;
}
public double distance(int x ,int y,int z){
double distance=Math.sqrt(Math.pow((this.x-x),2)+Math.pow((this.y-y),2)+Math.pow((this.z-z),2));
return distance;
}
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();//球的数量
int m=sc.nextInt();//小生物的数量
ArrayList<Ball> list=new ArrayList<>();//所有球
int[] res=new int[m];//每个小生物逃逸经过的球面数
for(int i=0;i<n;i++)
{
int xi=sc.nextInt();
int yi=sc.nextInt();
int zi=sc.nextInt();
int ri=sc.nextInt();
Ball ball=new Ball(xi,yi,zi,ri);
list.add(ball);
}
for(int i=0;i<m;i++)
{
int xi=sc.nextInt();
int yi=sc.nextInt();
int zi=sc.nextInt();
for(Ball b:list){
if(b.distance(xi,yi,zi)<b.r)
res[i]+=1;
}
}
for(int i:res)
System.out.print(i+" ");
}
}