c++ 覆盖所有点的最少线数(Minimum lines to cover all points)

示例图1 

示例图2 

        给定二维空间中的 N 个点,我们需要打印经过所有这 N 个点并且也经过特定 (xO, yO) 点的最少线数。

示例: 

        如果给定的点为 (-1, 3), (4, 3), (2, 1), (-1, -2), (3, -3) 且 (xO, yO) 点为 (1, 0),即每条线都必须经过此点。那么我们必须绘制至少两条线来覆盖所有经过 (xO, yO) 的点。

        我们可以通过考虑所有点的斜率(xO,yO)来解决这个问题。如果两个不同的点的斜率(xO,yO)相同,那么它们可以用同一条线覆盖,这样我们就可以跟踪每个点的斜率,每当我们得到一个新的斜率时,我们就将线数增加一。 

        在下面的代码中,斜率被存储为一对整数以消除精度问题,并使用一个集合来跟踪发生的斜率。 请参阅下面的代码以更好地理解。  

示例代码:

// C++ program to get minimum lines to cover 
// all the points 
#include <bits/stdc++.h> 
using namespace std; 
  
//    Utility method to get gcd of a and b 
int gcd(int a, int b) 

    if (b == 0) 
        return a; 
    return gcd(b, a % b); 

  
//    method returns reduced form of dy/dx as a pair 
pair<int, int> getReducedForm(int dy, int dx) 

    int g = gcd(abs(dy), abs(dx)); 
  
    //    get sign of result 
    bool sign = (dy < 0) ^ (dx < 0); 
  
    if (sign) 
        return make_pair(-abs(dy) / g, abs(dx) / g); 
    else
        return make_pair(abs(dy) / g, abs(dx) / g); 

  
/*    method returns minimum number of lines to 
    cover all points where all lines goes 
    through (xO, yO) */
int minLinesToCoverPoints(int points[][2], int N, 
                                   int xO, int yO) 

    //    set to store slope as a pair 
    set< pair<int, int> > st; 
    pair<int, int> temp; 
    int minLines = 0; 
  
    //    loop over all points once 
    for (int i = 0; i < N; i++) 
    { 
        //    get x and y co-ordinate of current point 
        int curX = points[i][0]; 
        int curY = points[i][1]; 
  
        temp = getReducedForm(curY - yO, curX - xO); 
  
        // if this slope is not there in set, 
        // increase ans by 1 and insert in set 
        if (st.find(temp) == st.end()) 
        { 
            st.insert(temp); 
            minLines++; 
        } 
    } 
  
    return minLines; 

  
// Driver code to test above methods 
int main() 

    int xO, yO; 
    xO = 1; 
    yO = 0; 
  
    int points[][2] = 
    { 
        {-1, 3}, 
        {4, 3}, 
        {2, 1}, 
        {-1, -2}, 
        {3, -3} 
    }; 
  
    int N = sizeof(points) / sizeof(points[0]); 
    cout << minLinesToCoverPoints(points, N, xO, yO); 
    return 0; 

输出: 
2

时间复杂度: O(N) 

辅助空间: O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值