本文的问题来自于知乎上和文章标题相同的提问
以位图左上角点为原点上平行边所在直线为x轴左平行边所在直线为y轴建立平面直角坐标系 x轴正向从左至右 y轴正向从上至下 将位图网格划分为小方块的一系列垂直边和水平边分别与x轴和y轴相交于一系列点 下文所涉及的所有坐标均指这些点在坐标轴上的坐标
先定义性质p1 p2 p3 的概念
对于坐标区间(a,b) a<=b 有a=a1<=b1 b1+1=a2 a2<=b2 b2+1=a3 ——an<=bn bn=b
对(a,b)的子区间(c,d)a<=c<=d<=b 若有c=ak d=bj 1<=k<=j<=n 则称(c,d)在划分ai bi 1<=i<=n 下对(a,b)满足性质p1
若有c=ak aj <= d <bj 1<=k<=j<=n 则称(c,d)在划分ai bi 1<=i<=n 下对(a,b)满足性质p2
若有ak <c <=bk d=bj 1<=k<=j<=n 则称(c,d)在划分ai bi 1<=i<=n 下对(a,b)满足性质p3
下面讨论算法
首先遍历第一行记录第一行所有黑色方块组成的最长黑色长条(a11,b11)———(a1n1,b1n1) a1i b1i(1<=i<=n1)分别为黑色长条的左端点横坐标和右端点横坐标a1i <= b1i
每个黑色长条单独组成一个矩形 用合适的数据结构保存和组织这些矩形 注意每个黑色长条彼此相离
如果第一层不存在黑色长条,直接忽略,继续遍历下一层
然后向下遍历第二行至第m行(m是整块位图矩阵的行数)中的每一行,对于当前遍历到的第i行,找出该行所有黑色方块组成的最长黑色长条(ai1,bi1)———(aini,bini) 注意这些黑色长条彼此相离 (如果第i层不存在黑色长条,忽略继续遍历下一层)考虑其中的每一个黑色长条(aij,bij )(1<=j<=ni) aij<=bij
如果第i-1层存在最长黑色长条那么 设其中某一个为(ai-1k,bi-1k) 1<=k<=ni-1
考虑在处理第i行黑色长条的过程中准备好处理(aij,bij)的时刻T 此时假定坐标元组(aij,bij)和坐标元组(ai-1k,bi-1k)不相离
设在处理完第i-1行后开始处理第i行时已计算出的底边在(ai-1k,bi-1k)上的一系列左右拼接的相邻矩形从左到右为Rk1,Rk2,—-,Rkv.它们的底边的左右端点横坐标组成的元祖依次为(Rk1l,Rk1r)—-(Rkvl,Rkvr)其中Rk1r+1=Rk2l,Rk2r+1=Rk3l——Rkv-1r+1=Rkvl 且Rk1l=ai-1k Rkvr=bi-1k Rk1l<=Rk1r —-
Rkvl<=Rkvr
在时刻T Rk1,Rk2,—-,Rkv在时刻T前第i行的处理过程(如果有)中可能有部分矩形底边被向下延长至第i行的黑色长条因而不再记录在(ai-1k,bi-1k)上 也可能有部分矩形一次或两次被平行于左平行边的直线一分为二,一部分的底边向下延长至第i行的黑色长条因而从(ai-1k,bi-1k)上消失,一部分保留在(ai-1k,bi-1k)上 其余矩形保持不变在T时刻仍然在(ai-1k,bi-1k)上
设T时刻最终保留在在(ai-1k,bi-1k)上的所有矩形为R’k1 R’k2 —R’kp 若aij小于ai-1k 令矩形O为R’k1否则令O为R’k1 R’k2 —R’kp中左平行边底端横坐标位于aij左侧且左平行边底端横坐标距离aij最近的矩形
记R’k1 R’k2 —R’kp中O及O之后的所有矩形为R"k1—R"ko它们的底边的左右端点横坐标组成的元祖依次为(R"k1l,R"k1r)—-(R"kvl,R"kvr)其中R"k1r+1=R"k2l,R"k2r+1=R"k3l——R"ko-1r+1=R"kol 且R"k1l=ai-1k R"kor=bi-1k R"k1l<=R"k1r —-
R"kol<=R"kor
情况一
如果黑色长条(aij,bij )正好位于(ai-1k,bi-1k)的正下方即ai-1k<=aij<=bij<=bi-1k 那么
如果(aij,bij)在划分R"kil R"kir 1<=i<=o 下对(R"k1l,bi-1k)满足性质p1 我们有aij=R"ktl bij=R"ker 1<=t<=e<=o 对任意u满足t<=u<=e 我们把黑色长条
(aij,bij)左端点横坐标为R"kul 右端点横坐标为R"kur的子长条合并到到矩形R"ku的下方形成一个新的矩形,更新并记录这个矩形
如果(aij,bij)在划分R"kil R"kir 1<=i<=o 下对(R"k1l,bi-1k)满足性质p2 我们有aij=R"ktl R"kel <= bij<R"ker 1<=t<=e<=o 对任意t<=u<e 我们把黑色长条(aij,bij )左端点横坐标为R"kul 右端点横坐标为R"kur的子长条合并到矩形R"ku的下方形成新矩形 更新记录该矩形 同时把黑色长条(aij,bij)左端点横坐标为R"kel右端点横坐标为bij的子长条合并到矩形R"ke中每一个横坐标小于等于bij的方块组成的子矩形的下方 更新并记录该矩形 然后记录R"ke中所有横坐标大于bij 的方块形成的划分出的新矩形 记录该矩形
如果(aij,bij)在划分R"kil R"kir 1<=i<=o 下对(R"k1l,bi-1k)满足性质p3 我们有R"ktl <aij<=R"ktr bij=R"ker 1<=t<=e<=o 对任意t<u<=e 我们把黑色长条(aij,bij )左端点横坐标为R"kul 右端点横坐标为R"kur的子长条合并到矩形R"ku的下方形成新矩形 更新记录该矩形 同时把黑色长条(aij,bij)左端点横坐标为aij右端点横坐标为R"ktr的子长条合并到矩形R"kt中每一个横坐标大于等于aij的方块组成的子矩形的下方 更新并记录该矩形 然后记录R"kt中所有横坐标小于aij 的方块形成的划分出的新矩形 记录该矩形
情况二
如果存在k,t使得对黑色长条(aij,bij)有
aij < ai-1k ai-1t<=bij<=bi-1t 1<=k<=t<=ni-1 且k=1 或 k >1 aij > bi-1k-1 则若黑色长条(aij,bij)左端点为ai-1t 右端点为bij的子长条(ai-1t,bij)在划分R"til R"tir 1<=i<=v 下对(ai-1t,bi-1t)满足性质p1则划分出该子长条仿照情况一处理子长条(ai-1t,bij)
同时将黑色长条左端点横坐标为aij 右端点横坐标为ai-1t - 1的子长条划分出来作为新矩形,记录该矩形
情况三
如果存在k,t使得对黑色长条(aij,bij)有
ai-1k<=aij<=bi-1k bij > bi-1t 1<=k<=t<=ni-1且t=ni-1 或 t<ni-1 bij < ai-1t+1
则若黑色长条(aij,bij)左端点为aij右端点为bi-1k的子长条(aij,bi-1k)在划分R"kil R"kir 1<=i<=v 下对(R"k1l, bi-1k)满足性质p1则划分出该子长条仿照情况一处理子长条(aij,bi-1k)
同时将黑色长条左端点横坐标为bi-1k + 1 右端点横坐标为bij的子长条划分出来作为新矩形,记录该矩形
情况四
若存在(ai-1k,bi-1k) (ai-1t,bi-1t)1<=k<t<=ni-1使得对黑色长条(aij,bij)有 ai-1k <=aij<=bi-1k ai-1t<=bij<=bi-1t 则若黑色长条(aij,bij)左端点为aij右端点为bi-1k的子长条(aij,bi-1k)在划分R"kil R"kir 1<=i<=v1 下对(R"k1l,bi-1k)满足性质p1 且 若黑色长条(aij,bij)左端点为ai-1t右端点为bij的子长条
(ai-1t,bij)在划分R"til R"tir 1<=i<=v2下对(ai-1t,bi-1t)满足性质p1 则划分出子长条(aij,bi-1k) (ai-1t,bij)分别按情况一处理 另外划分出黑色长条(aij,bij)的子长条(bi-1k + 1, ai-1t - 1)单独作为新矩形 记录该矩形
若黑色长条(aij,bij)左端点为aij右端点为bi-1k的子长条(aij,bi-1k)在划分R"kil R"kir 1<=i<=v1 下对(R"k1l,bi-1k)满足性质p1 且 若黑色长条(aij,bij)左端点为ai-1t右端点为bij的子长条
(ai-1t,bij)在划分R"til R"tir 1<=i<=v2下对(ai-1t,bi-1t)不满足性质p1 则划分出子长条(aij,bi-1k)按情况一处理,另外划分出黑色长条(aij,bij)的子长条(bi-1k + 1, bij)单独作为新矩形 记录该矩形
若黑色长条(aij,bij)左端点为aij右端点为bi-1k的子长条(aij,bi-1k)在划分R"kil R"kir 1<=i<=v1 下对(R"k1l,bi-1k)不满足性质p1 且 若黑色长条(aij,bij)左端点为ai-1t右端点为bij的子长条
(ai-1t,bij)在划分R"til R"tir 1<=i<=v2下对(ai-1t,bi-1t)满足性质p1 则划分出子长条(ai-1t,bij)按情况一处理,另外划分出黑色长条(aij,bij)的子长条(aij, ai-1t - 1)单独作为新矩形 记录该矩形
如果i-1层不存在黑色长条或存在但 (aij,bij)不满足情况一到情况四中的任何一种情况,则将 (aij,bij )视为一个新矩形,记录该新矩形
(aij,bij )(1<=j<=ni)全部处理完毕后继续遍历下一行
所有行遍历完毕后就得到了所求位图矩阵的划分矩形组