求n边形周长的k等分点坐标(今日头条)

这是一篇关于如何计算n边形周长的k等分点坐标的博客。题目来源于今日头条的笔试,要求从点P0开始,将n边形的周长等分为k段,每段长度相等。分析过程包括计算总距离,确定等分后每段的长度,然后找出所有距离为d的整倍数的边,并打印出对应的坐标。

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

题目

本题来自今天头条的笔试:
有一个n边形(P0, P1, ..., Pn), 每一条边皆为垂直或水平线段。现给定数值k,以P0为起点将n边形的周长分为k段,每段的长度相等,请打印出k等分点的坐标(T0, T1, ..., Tk)的坐标。

分析

1、可以计算出从第0个点,到第N个点的总距离,作为该点的一个属性保存。

2、那么第0个点的总距离即为该多版型周长

3、求出等分后每一段的长度d,那么等分的点到第0个点的距离肯定为d的整倍数。列举出d小于周长的整倍数。

4、遍历判断d整倍数所在的边。根据边的两个节点的大小关系,打印之。

Java实现

package com.algorithm;

import com.google.common.collect.Lists;
import org.junit.Test;

import java.util.ArrayList;

/**
 * Author: 赵晓辉
 * MIS: zhaoxiaohui03
 * Date: 2019/3/26 15:46
 * Email: zhaoxiaohui03@meituan.com
 * Desc:今日头条面试题,多边形平分,打印平分点
 */
public class TestAvgPointByJinRiTouTiao {

    @Test
    public void test() {
        ArrayList<Point> list = Lists.newArrayList();
        list.add(new Point(1, 1));
        list.add(new Point(1, 3));
        list.add(new Point(5, 3));
        list.add(new Point(5, 5));
        list.add(new Point(10, 5));
        list.add(new Point(10, 1));
    
        /*打印多少份*/
        int num = 13;
        /*总长度*/
        double sum = 0;

        /*计算从第0个点到当前点的总长度*/
        for (int i = 1; i < list.size(); i++) {
            /*当前点*/
            Point cur = list.get(i);
            /*上一个点*/
            Point last = list.get(i - 1);

            double length = distance(cur, last);
            /*计算长度*/
            cur.setSumLength(sum += length);
        }

        /*设置第0个点的总长度==周长*/
        list.get(0).setSumLength(sum += distance(list.get(0), list.get(list.size() - 1)));
        /*为计算方便,把第0个点加到list最后,这样list中有两个0号元素*/
        list.add(list.get(0));
        
        /*计算平均长度*/
        double avg = sum / num;
        System.out.println("总长度:" + sum);
        System.out.println("平均长度" + sum / num);

        /*平均长度的整倍数,即为等分点*/
        double[] avgArray = new double[num];
        for (int i = 0; i < num; i++) {
            avgArray[i] = (i + 1) * avg;
        }

        /*下一次开始比对的point的索引,这样避免不必要的比对*/
        int pointIndex = 1;
        for (int j = 0; j < num; j++) {
            double target = avgArray[j];
            for (int i = pointIndex; i < list.size(); i++) {
                Point cur = list.get(i);
                if (cur.getSumLength() > target) {
                    double diff = cur.getSumLength() - target;
                    Point pre = list.get(i - 1);
                    /*水平线,当前点与上一个点Y坐标的大小关系不确定*/
                    if (pre.getX() == cur.getX()) {
                        if (pre.getY() < cur.getY()) {
                            System.out.println("(" + cur.getX() + ",    " + (cur.getY() - diff) + ")");
                        } else {
                            System.out.println("(" + cur.getX() + ",    " + (cur.getY() + diff) + ")");
                        }
                    } else {/*垂直线,当前点与上一个点X坐标的大小关系不确定*/
                        if (pre.getX() < cur.getX()) {
                            System.out.println("(" + (cur.getX() - diff) + ",     " + cur.getY() + ")");
                        } else {
                            System.out.println("(" + (cur.getX() + diff) + ",     " + cur.getY() + ")");
                        }
                    }

                    /*下一回从当前的点开始遍历扫描,
                     *之所以不从下一个点开始,是因为有可能当前点和下一点中间存在多个要打印的点*/
                    pointIndex = i;
                    break;
                }
            }
        }
    }

    /**
     * 两个点的距离
     *
     * @param p1
     * @param p2
     * @return
     */
    public double distance(Point p1, Point p2) {
        return Math.pow(Math.pow(p1.getX() - p2.getX(), 2) + Math.pow(p1.getY() - p2.getY(), 2), 0.5);
    }

    class Point {
        int x;
        int y;

        /*从第0个点,到当前点的总长度
        * 第1个点总长度最小,
        * 第0个点总长度最大==周长*/
        double sumLength;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        public double getSumLength() {
            return sumLength;
        }

        public void setSumLength(double sumLength) {
            this.sumLength = sumLength;
        }
    }
}

输出

总长度:26.0
平均长度2.0
(1.0,     3)
(3.0,     3)
(5,    3.0)
(5.0,     5)
(7.0,     5)
(9.0,     5)
(10,    4.0)
(10,    2.0)
(9.0,     1)
(7.0,     1)
(5.0,     1)
(3.0,     1)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值