|
既然数学哥也同意了,那就没问题:
VAR M NUMBER;
VAR N NUMBER;
EXEC :M :=3;
EXEC :N :=3;
With d as ( -------所有点
select x,y,row_number() over(order by x,y) id
from (select level-1 x from dual connect by level<=:M+1)
,(select level-1 y from dual connect by level<=:N+1)
)
,e as (------所有边
select rownum id
, power(2,rownum) eb -------每条边用一位二进制表示
, ee.*
from (SELECT d1.x x1,d1.y y1,d2.x x2,d2.y y2
FROM d d1,d d2
WHERE d1.id<d2.id and (abs(d1.x-d2.x),abs(d1.y-d2.y)) in ((0,1),(1,0))
order by d1.x,d2.x,d1.y,d2.y
) ee
)
,c as (------每个格子以其最小坐标的点做代表
select power(2,d.id) id -------每个格子用一位二进制表示
,sum(e.eb) eb ---------这个格子的四条边的四个二进制位
,d.x
,d.y
from d
,e ------ 构成方块的四条边
where d.x<:M and d.y<:N
and (e.x1,e.y1,e.x2,e.y2) in
((d.x,d.y,d.x,d.y+1)
,(d.x,d.y,d.x+1,d.y)
,(d.x+1,d.y,d.x+1,d.y+1)
,(d.x,d.y+1,d.x+1,d.y+1)) ---- 四条边的端点坐标
group by d.id,d.x,d.y
)
,connects as ( -------找出所有相邻的方格
select c1.id id1,c2.id id2,c1.id+c2.id cb,c1.eb eb1,c2.eb eb2
from c c1,c c2
where c1.id<c2.id
and (abs(c1.x-c2.x),abs(c1.y-c2.y)) in ((0,1),(1,0))
)
,closed(cb,eb,rn) as ( --------找出所有单个的封闭区域(由若干个相邻的方格构成)
----- cb:构成区域的所有方块,eb:该区域的外轮廓 rn:用于去重复
select id,eb,1 from c
union all
select closed.cb+connects.cb-bitand(closed.cb,connects.cb) ------- BITOR加上新的方格
,closed.eb+decode(bitand(closed.cb,connects.id1),0,connects.eb1,connects.eb2) ------- BIT XOR加上新的轮廓,用XOR是因为区域内部的段都不能点亮,只需要外轮廓
-2*bitand(closed.eb,decode(bitand(closed.cb,connects.id1),0,connects.eb1,connects.eb2))
,row_number() over(partition by closed.cb+connects.cb-bitand(closed.cb,connects.cb) order by 1) rn ---按照区域形状去重复
from closed,connects
where closed.rn=1
and (bitand(closed.cb,connects.id1),bitand(closed.cb,connects.id2))
IN ((connects.id1,0),(0,connects.id2)) --- 两个连续的方格有一个在区域中,另一个在区域外
)
,area as (select distinct cb,eb from closed)
,shapes(bits,cb,eb) as ( -----所有封闭区域的组合
select cb,cb,eb from area
union all
select shapes.bits+area.cb,area.cb, shapes.eb+area.eb-bitand(shapes.eb,area.eb) ---BITOR 拼上新轮廓
from shapes,area
where shapes.cb<area.cb and bitand(shapes.bits,area.cb)=0
)
select count(DISTINCT eb) from shapes;
|
|