• LeetCode lcci 16.03 交点


    原本我想使用无限叠if-else的方式估计能解决, 但这样总归是不够优雅。

    使用点斜式在斜率上可能存在问题, 为了少写判断, 使用一般式描述直线。并且将坐标带入一般式就能直观判断点与直线的位置关系, 以此判断线段的位置关系

    完成关系判断后, 剩下的事就相当于求直线交点, 直接解方程又得判断条件, 不行, 这很麻烦...

    搜索? 二分x轴或y轴?同时考虑xy又得加条件, 太累了

    既然给定目标与样本...等等, 机器学习? 线性回归?

    反向传播...不对, 题目的条件明确(样本完全), 可以直接求最优解(xy)

    接下来就是转化成矩阵形式

    [egin{cases} a_1x + b_1y+c_1 = 0 \ a_2x + b_2y+c_2 = 0 end{cases} ]

    [egin{cases} a_1x + b_1y = -c_1 \ a_2x + b_2y = -c_2 end{cases} ]

    [egin{pmatrix} x&y end{pmatrix} egin{pmatrix} a_1&a_2\ b_1&b_2 end{pmatrix} = egin{pmatrix} -c_1&-c_2 end{pmatrix} \ egin{pmatrix} x&y end{pmatrix} egin{pmatrix} a_1&a_2\ b_1&b_2 end{pmatrix} egin{pmatrix} a_1&a_2\ b_1&b_2 end{pmatrix}^{-1} = egin{pmatrix} -c_1&-c_2 end{pmatrix} egin{pmatrix} a_1&a_2\ b_1&b_2 end{pmatrix}^{-1} \ egin{pmatrix} x&y end{pmatrix} = egin{pmatrix} -c_1&-c_2 end{pmatrix} egin{pmatrix} a_1&a_2\ b_1&b_2 end{pmatrix}^{-1} ]

    接下来就是二阶矩阵求逆矩阵

    [egin{pmatrix} a&b\ c&d end{pmatrix}^{-1} = frac{1}{det} egin{pmatrix} d&-b\ -c&a end{pmatrix} \ egin{pmatrix} a&b\ c&d end{pmatrix}^{-1} = frac{1}{ad - bc} egin{pmatrix} d&-b\ -c&a end{pmatrix} ]

    由于在一般式阶段已经可以完成一些判断, 过滤特殊情况, 所以行列式det已经不为0, 直接计算逆矩阵带入后就能得到交点(x, y)

    _(:з」∠)_

    如果从行列式角度直接讨论无解/多解/唯一解, 似乎需要线性变换, 太麻烦...不管了

    C艹

    class Solution {
    public:
        struct pit {
            int x, y;
            
            bool operator<(const pit &b) const {
                if (x != b.x) return x < b.x;
                return y < b.y;
            }
        };
        
        vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {
            if (std::max(start1[0], end1[0]) < std::min(start2[0], end2[0])) return {};
            if (std::max(start1[1], end1[1]) < std::min(start2[1], end2[1])) return {};
            
            int a1 = start1[1] - end1[1], b1 = end1[0] - start1[0];
            int c1 = -(a1*end1[0] + b1*end1[1]);
            
            int v1 = a1*start2[0] + b1*start2[1] + c1;
            int v2 = a1*end2[0] + b1*end2[1] + c1;
            if (v1*v2 > 0) return {};
            
            if (v1 == v2) {
                pit ary[4] = {
                    {start1[0], start1[1]}, {end1[0], end1[1]},
                    {start2[0], start2[1]}, {end2[0], end2[1]},
                };
                std::sort(ary, ary + 4);
                return {double(ary[1].x), double(ary[1].y)};
            }
            
            int a2 = start2[1] - end2[1], b2 = end2[0] - start2[0];
            int c2 = -(a2*end2[0] + b2*end2[1]);
            
            v1 = a2*start1[0] + b2*start1[1] + c2;
            v2 = a2*end1[0] + b2*end1[1] + c2;
            if (v1*v2 > 0) return {};
            
            double detL = a1*b2 - a2*b1;
            double L[2][2] = {
                {b2/detL, -a2/detL},
                {-b1/detL, a1/detL},
            };
            double optX = -c1*L[0][0] + -c2*L[1][0];
            double optY = -c1*L[0][1] + -c2*L[1][1];
            return {optX, optY};
        }
    };
    
  • 相关阅读:
    java 新建文件夹保存
    android AppWidgwtProvider学习
    GPS定位
    android ContentProvider学习
    Android 解屏幕锁与点亮屏幕(来电时效果)
    RecyclerView 分页滑动,设置可以滑动下一页,下一个item作为起点方法
    Glide 加载图片 到动态ImageView
    一个例子了解 HandlerThread,Looper,ThreadLocal,Handler,MessageQueue,Message的关系
    android TabLayout 相关
    屏幕相关
  • 原文地址:https://www.cnblogs.com/Simon-X/p/13961724.html
Copyright © 2020-2023  润新知