Graphics


CST PA1

1-2 A+B Graphics

算法构思

容易想到先将横轴和纵轴的端点进行排序预处理, 进而确定 $n$ 条线段的具体端点. 通过二分查找, 对于其中每条线段使用 ToLeft 测试来判断其与所给出点 $P$ 和原点 $O$ 的连线段 $OP$ 是否有交点, 高效查找出临界交点, 进而确定总交点的数目.

进行ToLeft 测试判断两条直线是否有交点, 可以先算出 $n$ 条线段相应横纵坐标乘积并存储, 以便进行 ToLeft 测试时无需重复计算, 优化算法时间性能.

由于端点坐标数据范围为 $[1, 2^{31})$, 选用 $\text{long long}$ 数组来存储坐标与相应乘积; 二分查找时对于几种临界情况进行了特殊处理与返回, 主要包含全无交点与全部交点两种情况.

参考资料

对 $x$ 轴和 $y$ 轴上的点坐标进行排序主要参考了此文章, 选择了 <stdlib.h> 中的 qsort() 函数;

复杂度估计

数据输入过程的时间复杂度为 $O(n)$; 数据排序过程的时间复杂度为 $O(nlogn)$.

而算法时间复杂度主要来自二分查找交点的过程:

...
// Line 13
// cross 函数返回与线段 OP 存在交点的最上方线段标号.
int cross (...) { 
    if (n == 1) {
        ...
    }
    else {
        int low = 0;  
        int high = n - 1;  
        int mid = 0; 
        while (low <= high) {  
            mid = (low + high) / 2;  
                ...
        }
    }
    return -1;
} 
...

其中每经过一次 while 循环都要访问若干次 toleft 函数, 此函数调用的时间为常数时间, 因此 cross 函数的时间复杂度与二分查找相同, 为 $O(logn)$.

进而对于 $n$ 条线段信息的输入, 进行 $m$ 次查询, 算法的时间复杂度为 $O(mlogn)$.

算法空间复杂度主要来自存储横纵坐标与相应乘积的过程:

...
long long x[n] = {0};
long long y[n] = {0};
long long z[n] = {0};
...

正比于输入数据的数目, 对于 $n$ 条线段信息的输入, 算法的空间复杂度为 $O(n)$.


文章作者: Chengsx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Chengsx !
  目录