简体   繁体   English

如何找到通过给定点(a,b)和(x,0)的线的最大y轴截距?

[英]How to find largest y-intercept of lines through given points (a, b) and (x, 0)?

I have given points (a, b) and then I have given points (x, 0) . 我给了点(a, b) ,然后给了点(x, 0) Now for each point (x, 0) I make lines with all points (a, b) (see image). 现在,对于每个点(x, 0)我用所有点(a, b)(a, b)线(见图)。
For each point (x, 0) I have to return indexes of thease point/points (a, b) which y-intercept of line through this point/points and point (x, 0) is largest. 对于每个点(x, 0)我必须返回一个或多个酶点(a, b)索引,通过该点的直线与点(x, 0) y截距最大。
All x values of points (x, 0) are greater than maximum a . (x, 0)所有x值都大于最大值a Numbers a, b, x are positive integers. 数字a, b, x是正整数。

Example: 例:

Input 输入

3 4 (number of (a, b) points and number of (x, 0) points - let's call them m and n)
5 3 (point A, index 0)
14 1 (point C, index 1)
10 2 (point B, index 2)
16 20 40 15 (x values of points (x, 0)) 

Output 产量

1
0 2
0
1

该示例的点(16,0)(svg)的图像

My solution: 我的解决方案:

int main() {
    int m, n;
    cin >> m >> n;
    vector<pair<int, int>> pointsAB(m);

    for (int i = 0; i < m; ++i) {
        cin >> pointsAB[i].first >> pointsAB[i].second;
    }

    for (int j = 0; j < n; ++j) {
        int currX;
        double minSlope = 1.00;
        vector<int> indexes;
        cin >> currX;
        for (int i = 0; i < m; ++i) {
            int a = pointsAB[i].first, b = pointsAB[i].second;
            double currSlope = -((double)b) / (currX - a);
            if (currSlope < minSlope) {
                indexes.clear();
                minSlope = currSlope;
                indexes.push_back(i);
            }
            else if (currSlope == minSlope) {
                indexes.push_back(i);
            }
        }

        cout << indexes[0];
        for (int k = 1; k < indexes.size(); ++k) {
            cout << " " << indexes[k];
        }
        cout << '\n';
    }

    return 0;
}

My solution to this problem has time complexity O(m * n) but this doesn't seem very efficient to me. 我对这个问题的解决方案具有时间复杂度O(m * n),但这对我来说似乎不是很有效。 My question is can be this problem solved with better time complexity and how? 我的问题是可以用更好的时间复杂度解决这个问题吗?

Build convex hull for a/b points, get only top half (really you need only right leg of upper envelope) in order from the most right point 为a / b点构建凸包 ,从最右边的点开始仅获取上半部分(确实只需要上信封的右腿)

Sort x-points 排序x点

Complexity is about O(mlogm + nlogn ) (depending on hull and sorting methods) 复杂度约为O(mlogm + nlogn )(取决于船体和排序方法)

Walk through x-list in order from small values, finding the best points of a/b set. 从较小的值开始按顺序浏览x列表,找到a / b集的最佳点。 Note that this process is linear O(n+m) (we will find next best a/b point only to the left of current one - imagine rotating stick, one end moves along OX axis, another end rests on the a/b point set) 请注意,此过程是线性O(n+m) (我们将仅在当前对象的左侧找到次佳的a / b点-想象旋转的棒,一端沿OX轴移动,另一端位于a / b点上组)

Most of the steps here seem fairly obvious: 这里的大多数步骤似乎都很明显:

  1. read in the points 阅读要点
  2. read in the X-intercept for each line (did I just invent "x-intercept"?) 在每行的X截距中读取(我刚刚发明了“ X截距”吗?)
  3. compute the slopes of the lines 计算线的斜率
  4. select the smallest slope 选择最小斜率
  5. find all the lines with that slope 找到那个斜率的所有线
  6. print out the results 打印结果

I believe all of those can be done with O(N) complexity, so it should be O(N) overall. 我相信所有这些都可以通过O(N)复杂度完成,因此总体上应该是O(N)。

#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>

struct point {
    int x;
    int y;

    friend std::istream &operator>>(std::istream &is, point &p) {
        return is >> p.x >> p.y;
    }

    friend std::ostream &operator<<(std::ostream &os, point const &p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }
};

struct slope_index {
    double slope;
    int index;

    bool operator<(slope_index const &other) const {
        return slope < other.slope;
    }

    bool operator==(slope_index const &other) const {
        return slope == other.slope;
    }
};

int main() {
    int N;
    std::cin >> N;

    // read in the points
    std::vector<point> points;
    std::copy_n(std::istream_iterator<point>(std::cin), N, std::back_inserter(points));

    // read in the X-intercept for each point:
    std::vector<int> Xs;
    std::copy_n(std::istream_iterator<int>(std::cin), N, std::back_inserter(Xs));

    // compute the slopes
    std::vector<slope_index> slopes;
    int i = 0;
    std::transform(points.begin(), points.end(),
        Xs.begin(),
        std::back_inserter(slopes),
        [&](point const &p, int currX) { return slope_index{ p.y / double(p.x - currX), i++ }; });

    // find the smallest slope
    auto v = *std::min_element(slopes.begin(), slopes.end());

    // find all the lines with that slope:
    auto pos = std::partition(slopes.begin(), slopes.end(), [&](auto const &s) { return v == s; });

    // print out the results:
    for (auto s = slopes.begin(); s != pos; ++s)
        std::cout << points[s->index];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用三个点(x,y),如何查找是否为三角形 - Using three points (x, y), How to find whether it is triangle or not 给定两个点(x1,y1)(x2,y2),我该如何平均计算给定点之间的直线上的N个不同点 - Given two points (x1,y1) (x2,y2), how can I compute N different points evenly lying on the line between the given points 通过给定点的最小行数 - Minimum count of lines that goes through the given points 查找给定x,y,z坐标的方向 - Find direction of given x,y,z cordinates 指定为XY坐标的点之间的最短路径距离 - Shortest Path distance between points given as X-Y coordinates 如何在给定图中找到最大的二分子图? - How to find largest bi-partite subgraph in the given graph? 如果以像素为单位给出两条线(外部和内部)之间的边距,如何计算(x,y)坐标? - How can one calculate (x,y) co-ordinates if margin between two lines(outer and inner) are given in terms of pixels? 如何计算圆的内/外/外有多少个坐标为(x; y)的点 - How to calculate how many points with coordinates (x;y) is in/on/outside of circle 需要找到组成最大周长的 3 个点 - Need to find 3 points that make up the largest perimeter 如何找到最大的轮廓? - How to find the largest contour?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM