2016 微软秋招(校招)在线笔试 题目1 : Farthest Point

本篇介绍了一个算法问题:给定平面上的一个圆,寻找该圆上距离圆心最远的整数坐标点,并提供了一种解决方案。考虑了不同情况下的边界条件,并通过遍历可能的点来找到答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目1 : Farthest Point
时间限制:5000ms
单点时限:1000ms
内存限制:256MB
描述
Given a circle on a two-dimentional plane.

Output the integral point in or on the boundary of the circle which has the largest distance from the center.

输入
One line with three floats which are all accurate to three decimal places, indicating the coordinates of the center x, y and the radius r.

For 80% of the data: |x|,|y|<=1000, 1<=|r|<=1000

For 100% of the data: |x|,|y|<=100000, 1<=|r|<=100000

输出
One line with two integers separated by one space, indicating the answer.

If there are multiple answers, print the one with the largest x-coordinate.

If there are still multiple answers, print the one with the largest y-coordinate.

样例输入
1.000 1.000 5.000
样例输出
6 1


//未优化版本
import java.util.LinkedList;
import java.util.Scanner;

class Point{
    public long x;
    public long y;
    public Point(long X, long Y){
        this.x = X;
        this.y = Y;
    }
}
public class T1 {
    public static boolean isInCircle(long x, long y, double x0, double y0, double r){
        if(distance_2(x, y, x0, y0) <= r*r){
            return true;
        } else {
            return false;
        }
    }
    public static double distance_2(long x, long y, double x0, double y0){
        double deltaX = x - x0;
        double deltaY = y - y0;
        return deltaX * deltaX + deltaY * deltaY;
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double x,y,r;
        x = input.nextDouble();
        y = input.nextDouble();
        r = input.nextDouble();
        long left = (int)(x - r), right = (int)(x + r), top = (int)(y + r), bottom = (int)(y - r);
        double maxDistance = 0;

        LinkedList<Point> points = new LinkedList<Point>();

        for(long i = left; i <= right; i++){
            if(isInCircle(i, top, x, y, r)){
                double curDistance = distance_2(i, top, x, y);
                if(curDistance >= maxDistance){
                    maxDistance = curDistance;
                    points.add(new Point(i, top));
                }
            }
        }
        for(long i = left; i <= right; i++){
            if(isInCircle(i, bottom, x, y, r)){
                double curDistance = distance_2(i, bottom, x, y);
                if(curDistance >= maxDistance){
                    maxDistance = curDistance;
                    points.add(new Point(i, bottom));
                }
            }
        }
        for(long i = bottom; i <= top; i++){
            if(isInCircle(left, i, x, y, r)){
                double curDistance = distance_2(left, i, x, y);
                if(curDistance >= maxDistance){
                    maxDistance = curDistance;
                    points.add(new Point(left, i));
                }
            }
        }

        for(long i = bottom; i <= top; i++){
            if(isInCircle(right, i, x, y, r)){
                double curDistance = distance_2(right, i, x, y);
                if(curDistance >= maxDistance){
                    maxDistance = curDistance;
                    points.add(new Point(right, i));
                }
            }
        }

        for(Point pt : points){
            if(distance_2(pt.x,pt.y, x, y) < maxDistance){
                points.remove(pt);
            }
        }

        long maxX = points.get(0).x;
        LinkedList<Point> resultPts = new LinkedList<Point>();
        for(Point pt : points){
            if(pt.x > maxX){
                maxX = pt.x;
            }
        }
        for(Point pt : points){
            if(pt.x == maxX){
                resultPts.add(pt);
            }
        }

        Point resultPt = resultPts.get(0);

        for(Point pt : resultPts){
            if(pt.y > resultPt.y){
                resultPt = pt;
            }
        }
        System.out.println(resultPt.x+" "+resultPt.y);
    }

}
<think>我们被要求使用FPS(FarthestPointSampling)算法将点云下采样到1024个点。FPS算法的核心思想是逐步选择距离已选点集最远的点,从而保证采样点尽可能覆盖整个点云。根据引用[1][2][3]的描述,FPS的步骤可概括为:1.从点云中随机选择一个初始点作为第一个采样点。2.计算所有点到已选采样点集的最近距离(即每个点到已选点集中最近点的距离)。3.选择具有最大最近距离的点作为下一个采样点。4.重复步骤2-3,直到选中的点数达到目标数量(如1024)。下面我们使用Python和PyTorch实现FPS算法,并使用Open3D进行可视化。注意:在点云处理中,FPS常用于深度学习的采样层(如PointNet++),但这里我们独立实现。代码步骤:1.导入必要的库(numpy,open3d,torch等)。2.实现FPS函数,输入点云(N,3)和目标点数,返回采样后的点索引。3.加载点云数据,进行采样,并可视化结果。注意:由于FPS是迭代过程,当点云很大时可能较慢,因此我们使用矩阵运算来加速。下面给出完整的代码示例:</think> ### 使用Farthest Point Sampling (FPS)将点云采样至1024点 **最远点采样(FPS)**是一种基于空间分布的点云采样方法,其核心思想是不断选择距离当前采样点集合最远的点,从而保证采样点均匀覆盖整个点云空间并保持几何特征[^1]。以下是具体实现方法: #### 算法原理[^1][^3] 设原始点云有$N$个点: 1. **初始化**:随机选择第一个点$P_0$,采样集合$S = \{P_0\}$ 2. **距离更新**:计算每个点到$S$的最近距离: $$\text{distance}[i] = \min_{P_j \in S} \|P_i - P_j\|$$ 3. **采样新点**:选择$\text{distance}$最大值对应的点$P_k$加入$S$ 4. **迭代**:重复步骤2-3,直到$|S| = 1024$ #### Python实现代码 ```python import torch import open3d as o3d def farthest_point_sample(xyz, npoint): """ FPS点云采样 :param xyz: 点云坐标 [B, N, 3] :param npoint: 目标点数 :return: 采样点索引 [B, npoint] """ device = xyz.device B, N, C = xyz.shape centroids = torch.zeros(B, npoint, dtype=torch.long).to(device) distance = torch.ones(B, N).to(device) * 1e10 farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device) for i in range(npoint): centroids[:, i] = farthest centroid = xyz[torch.arange(B), farthest, :].view(B, 1, 3) dist = torch.sum((xyz - centroid) ** 2, -1) # [B, N] mask = dist < distance distance[mask] = dist[mask] # 更新最近距离 farthest = torch.max(distance, -1)[1] # 选择最远点索引 return centroids # 使用示例 pcd = o3d.io.read_point_cloud("input.ply") # 读取点云 points = torch.tensor(pcd.points).unsqueeze(0) # 转为Tensor [1, N, 3] # FPS采样至1024点 indices = farthest_point_sample(points, 1024) sampled_points = points[0, indices[0], :] # 创建采样后点云 sampled_pcd = o3d.geometry.PointCloud() sampled_pcd.points = o3d.utility.Vector3dVector(sampled_points.numpy()) # 可视化对比 o3d.visualization.draw_geometries([pcd]) # 原始点云 o3d.visualization.draw_geometries([sampled_pcd]) # 采样后点云 ``` #### 关键特点 1. **特征保持** FPS通过最大化点间距保持空间分布特性,尤其擅长保留: - 物体轮廓特征[^2] - 曲面曲率变化区域 - 几何边缘和角落 2. **自适应采样密度** 在曲率大的区域自动提高采样密度: $$ \text{sampling density} \propto \frac{1}{\min \|P_i - P_j\|} $$ 3. **性能优化建议** - 使用**批处理矩阵运算**(如上述PyTorch实现)提升速度 - 预处理构建**KD-Tree**加速距离查询 - 结合**随机初始点选择**增强结果鲁棒性[^3] #### 不同采样方法对比 | 方法 | 特征保留率 | 均匀性 | 复杂度 | |-------------|------------|--------|------------| | FPS[^1] | >90% | 优秀 | $O(kN)$ | | 随机采样 | <60% | 中等 | $O(1)$ | | 网格采样 | 70-80% | 良好 | $O(N)$ | > **典型应用场景**:3D物体识别[^2]、点云配准、曲面重建
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值