JAVA程序设计:平分正方形(面试题 16.13)

该博客介绍了一个算法问题,涉及如何找到一条直线将两个正方形分割成相等的两半。算法首先找到正方形的中心点,然后根据中心点的位置关系计算直线方程。如果中心点在同一水平线上,返回与Y轴平行的直线;若在垂直线上,返回与X轴平行的直线;否则,计算斜率最大的直线。最后,返回这条直线与正方形边界的两个最远端点坐标。
摘要由CSDN通过智能技术生成

给定两个正方形及一个二维平面。请找出将这两个正方形分割成两半的一条直线。假设正方形顶边和底边与 x 轴平行。

每个正方形的数据square包含3个数值,正方形的左下顶点坐标[X,Y] = [square[0],square[1]],以及正方形的边长square[2]。所求直线穿过两个正方形会形成4个交点,请返回4个交点形成线段的两端点坐标(两个端点即为4个交点中距离最远的2个点,这2个点所连成的线段一定会穿过另外2个交点)。2个端点坐标[X1,Y1]和[X2,Y2]的返回格式为{X1,Y1,X2,Y2},要求若X1 != X2,需保证X1 < X2,否则需保证Y1 <= Y2。

若同时有多条直线满足要求,则选择斜率最大的一条计算并返回(与Y轴平行的直线视为斜率无穷大)。

示例:

输入:
square1 = {-1, -1, 2}
square2 = {0, -1, 2}
输出: {-1,0,2,0}
解释: 直线 y = 0 能将两个正方形同时分为等面积的两部分,返回的两线段端点为[-1,0]和[2,0]
提示:

square.length == 3
square[2] > 0

思路:我们首先找到两个正方形的中心点,我们知道,对于每个正方形,若想平分这个正方形,则直线必须经过这个中心点,因此若想平分这两个正方形,则我们需要所求直线同时经过这两个中心点,而两点能确定一条直线。剩下就是分类讨论而已。

class Solution {
    public double[] cutSquares(int[] square1, int[] square2) {
        double[] centerPoints1 = find(square1);
        double[] centerPoints2 = find(square2);
        if (centerPoints1[0] == centerPoints2[0]) {
            return new double[]{centerPoints1[0], Math.min(square1[1], square2[1]),
                    centerPoints1[0], Math.max(square1[1] + square1[2], square2[1] + square2[2])};
        } else if (centerPoints1[1] == centerPoints2[1]) {
            double x = Math.min(square1[0], square2[0]);
            double xx = Math.max(square1[0] + square1[2], square2[0] + square2[2]);
            return new double[]{x, centerPoints1[1], xx, centerPoints2[1]};
        } else {
            double k = (centerPoints1[1] - centerPoints2[1]) / (centerPoints1[0] - centerPoints2[0]);
            double b = centerPoints1[1] - k * centerPoints1[0];
            double y = Math.min(square1[1], square2[1]);
            double x = (y - b) / k;
            double yy = Math.max(square1[1] + square1[2], square2[1] + square2[2]);
            double xx = (yy - b) / k;
            double xmin = Math.min(square1[0], square2[0]);
            double xmax = Math.max(square1[0] + square1[2], square2[0] + square2[2]);
            if (x < xmin) {
                x = xmin;
                y = k * x + b;
            }
            if (x > xmax) {
                x = xmax;
                y = k * x + b;
            }
            if (xx < xmin) {
                xx = xmin;
                yy = k * xx + b;
            }
            if (xx > xmax) {
                xx = xmax;
                yy = k * xx + b;
            }
            if (x < xx || x == xx && y <= yy)
                return new double[]{x, y, xx, yy};
            else
                return new double[]{xx, yy, x, y};
        }
    }

    private double[] find(int[] arr) {
        return new double[]{(2.0 * arr[0] + arr[2]) / 2, (2.0 * arr[1] + arr[2]) / 2};
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值