• [LeetCode] Max Points on a Line


    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

    思路:

    (1)点1到点n

            (a)以点1为参考点,求“点1”与“点2到点n”各个斜率下点的个数; (求出直线最多的点数值max1)

            (b)以点2为参考点,求“点2”与“点3到点n”各个斜率下点的个数;  (求出直线最多的点数值max2,

                      注意:(b)里的直线有可能与(a)中的某条直线重合,但由于这条直线在(b)中少了点1,则直线上点的个数

                      肯定比(a)中的直线上的点的个数少,不影响(2)中结果的判断。

               ...

             (n-1)以点n-1为参考点,求“点n-1”与“点n”斜率下点的个数;(求出直线最多的点数值maxn_1)

    (2)则maxNum = max(max1,max2,maxn_1) ;

     ps:(考虑到参考点可能会有好几个点的情况)

           (考虑到垂直时的情况)

    注意事项:

    (1) (0,0)(0,0)点算是两个点;

    (2)  注意斜率k计算过程中,虽然k声明为double型,但如果被除数和除数都是整形的话,k也会退化为int型,导致结果不正确。

    (3)其他注意事项见程序注释部分,写的很详细。

     
     struct Point {
          int x;
          int y;
          Point() : x(0), y(0) {}
          Point(int a, int b) : x(a), y(b) {}
      };
     
    class Solution { 
    public:
        int maxPoints(vector<Point> &points) {
    
            int maxNum = 0;
            for(vector<Point>::iterator iter=points.begin();iter != points.end();iter++)
            {
                int numOfVerticle=1;//参考点算1个,所以初始值是1不能是0;
                double k;
                map<double,int> numOfALine;
                
                int numOfRef = 1; 
    
               for(vector<Point>::iterator iter1 = iter+1;iter1 != points.end();iter1++ )
               {
                 if(iter->x == iter1->x)
                 {
                    numOfVerticle++;      //已经添加了参考点的个数
                    if(iter->y == iter1->y)
                        numOfRef++;     //设置参考点的个数,参考点有可能有相同的其他几个点,比如(0,0),(0,0)算作不同的2个点
                 }
                 else
                 {
                    k = 1.0*(iter1->y - iter->y)/(iter1->x - iter->x);//一定要乘以1.0,否则k=2.9也会当作k = 2处理。或者把被除数强制转换为double
                                                                      //即  k = double(iter1->y - iter->y)/(iter1->x - iter->x);
                    ++numOfALine[k];   //注意此处没有添加参考点的个数;
                 }
               }       
               
               for(map<double,int>::iterator iter2 = numOfALine.begin();iter2 != numOfALine.end();iter2++)
               {
                   if(maxNum < (iter2->second+numOfRef))//注意iter2统计的是以(*iter)为参考点,不同斜率的点数,所以要加上参考点的个数;
                       maxNum = (iter2->second+numOfRef);
               
               }
               if(maxNum<numOfVerticle)
                   maxNum = numOfVerticle;
            
            }
            return maxNum;  
        }
    };

     下面这是以前写的,考虑的更加严谨,参考一下:

    class Solution {
    public:
        int maxPoints(vector<Point> &points) 
        {
            if(points.size()==0)
                return 0;
            else if(points.size()==1)
                return 1;
            else
            {
            map<double,int>slope_count;
        
            int res=1;
            for(vector<Point>::iterator iter=points.begin();iter!=points.end();iter++)
            {
                int same_count(0),vertical_count(0);
                slope_count.clear();
                for(vector<Point>::iterator iter1=iter+1;iter1!=points.end();iter1++)
                {
                    if(iter->x==iter1->x)
                        {
                            if(iter->y == iter1->y)
                            same_count++;
                            else
                            vertical_count++;
                        }
                    else
                        {
                            double slope=1.0*(iter->y - iter1->y)/(iter->x-iter1->x);
                            ++slope_count[slope];
                        }
                }
                res=(res>(same_count+vertical_count+1)?res:(same_count+vertical_count+1));
                for(map<double,int>::iterator itera=slope_count.begin();itera!=slope_count.end();itera++)
                    res=(res > (itera->second+same_count+1)) ? res : (itera->second+same_count+1);
            }
            return res;
        }
        }
    };
  • 相关阅读:
    Codeforces1101G (Zero XOR Subset)-less 【线性基】【贪心】
    Codeforces1101F Trucks and Cities 【滑动窗口】【区间DP】
    HDU4651 Partition 【多项式求逆】
    BZOJ2554 color 【概率DP】【期望DP】
    codeforces1101D GCD Counting 【树形DP】
    codechef EBAIT Election Bait【欧几里得算法】
    BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】
    codeforces1093G Multidimensional Queries 【线段树】
    BZOJ3277 串 【后缀数组】【二分答案】【主席树】
    AHOI2013 差异 【后缀数组】
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3775544.html
Copyright © 2020-2023  润新知