光影切割
在一个平面内有一个矩形区域,直线穿过矩形可以将其分割为不同的区域,且在这个平面中不存在三条直线相交一点的情况。求当有N条直线穿过矩形时,它被分割为多少个区域?
解法一:
平面倍划分成多少块的问题可以转化为直线的交点有多少个的问题。
两条直线-->一个交点-->空间分成4个部分
三条直线-->两个交点-->空间分成6个部分
三条直线-->三个交点-->空间分成7个部分
每增加一条直线,如果增加M个交点,那么这条直线被新增加的M个交点,分成M+1段。每一段直线会将原来一块区域分成两块,因此,新增加M+1块新区域。
如果总共有N条直线,M个交点,那么区域的数目为N+M+1。如何证明?将N条直线逐一投影到坐标区间上,假设第K条直线与之前的K-1条直线的焦点为Nk个,那么它使得区间内的区域块增加Nk+1个。则N条直线投影完毕后,所有区域块的数目为:
1+sigma(Nk+1)(1-->n)=1+N+sigma(Nk)(1-->n)=1+N+M
因此,求出所有直线两两相交的交点,然后再查找落在区间内的交点,就可以计算出划分的区域块数。将所有交点存储于数组Intersect中,然后计算。这样,算法的复杂度就转化为查找交点数组的问题了。
数组初始化,即计算所有交点,时间复杂度为O(N^2)。每次查询的时间复杂度为O(M)。
如果在初始化后对所有交点按X轴坐标排序,则复杂度为O(N^2+M*logM),之后进行二分查找,每次查找的时间复杂度为O(logM)。
解法二:
一个交点的情况,两条直线与左边界的交点顺序为(a,b),与右边界的交点顺序为(b,a),顺序反过来了。如果没有交点,则顺序不变。
区域内的交点数目等于一个边界上交点顺序相对另一个边界交点顺序的逆序总数(利用到条件“没有三条直线相交于一个点”)。
问题转化为求一个N个元素数组的逆序数。
求解逆序数的直接方法时间复杂度为O(N^2),若用分治策略,可降为O(N*logN)。分治思想如下:求前N/2个元素的逆序数,再求后N/2个元素的逆序数,最后在排序过程中合并前后两部分之间的逆序数。