|
第11题我是用SQL试图找出少于7个的各种组合,结果没有一个能够拼成18*19的矩形:
WITH s AS (SELECT LEVEL n,LEVEL*LEVEL a FROM DUAL CONNECT BY LEVEL<=18) ---- 各种尺寸,从1到18
,s2 AS ( -------- 每种尺寸的所有可能个数,最多不超过7个
SELECT n
,cnt
,a*cnt AS a ------- 面积
FROM s,(SELECT LEVEL cnt FROM DUAL CONNECT BY LEVEL<8)
WHERE a*cnt<=18*19
)
,t(n,cnt,a,path) AS ( ------ 递归找出各种尺寸以及不同个数的组合
SELECT n,cnt,a,CAST(n||'*'||cnt AS VARCHAR2(200)) path
FROM s2
UNION ALL
SELECT s2.n,t.cnt+s2.cnt,t.a+s2.a,t.path||','||s2.n||'*'||s2.cnt
FROM t,s2
WHERE t.n<s2.n
AND t.cnt+s2.cnt<8
AND t.a+s2.a<=18*19
)
,r AS ( ------ 所有拼起来总面积相符的组合,可能是答案
SELECT /*+ materialize */ ROWNUM id,cnt,path FROM t WHERE a=18*19 AND cnt<8
)
,r2 AS ( ---------- 每种尺寸的正方形拆成一行, 其个数为s_cnt
SELECT id,cnt
,TO_NUMBER(REGEXP_SUBSTR(str,'[^*]+',1,1)) s
,REGEXP_SUBSTR(str,'[^*]+',1,2) s_cnt
,path
FROM (
SELECT r.*,REGEXP_SUBSTR(path,'[^,]+',1,n) str
FROM r,(SELECT LEVEL n FROM DUAL CONNECT BY LEVEL<=8)
)
WHERE str IS NOT NULL
)
,r3 AS (
SELECT *
FROM (
SELECT r3.*,SUM(CASE WHEN rn<=2 THEN s END) OVER(PARTITION BY id) sum2 ---- 每一组中最大的两个加起来不得越界
FROM ( ---------- 把上述结果的每种正方形再拆成每个一行(每种有s_cnt行)
SELECT id, path, id*100+n AS sq_id,cnt,s,ROW_NUMBER() OVER(PARTITION BY id ORDER BY s DESC) rn
FROM r2,(SELECT LEVEL n FROM DUAL CONNECT BY LEVEL<=8)
WHERE n<=s_cnt
) r3
)
WHERE sum2<=19
)
,t2(id,cnt,path,sq_id,s) AS ( ------- 每组答案中必定有几个正方形的边之和为18或者19
SELECT id,cnt,path,sq_id,s FROM r3
UNION ALL
SELECT t2.id,t2.cnt,t2.path,r3.sq_id,t2.s+r3.s FROM t2,r3 WHERE t2.id=r3.id AND t2.sq_id<r3.sq_id
)
SELECT cnt,path
FROM t2
WHERE s IN (18,19)
GROUP BY id,path,cnt
HAVING COUNT(DISTINCT s)=2;
CNT PATH
----------------------
5 4*1,8*1,9*2,10*1
6 1*1,7*2,9*3
6 2*1,5*1,8*3,11*1
6 5*1,7*4,11*1
6 5*2,7*1,9*3
6 6*3,7*1,8*1,11*1
7 1*1,3*1,5*1,8*1,9*3
7 1*2,4*1,9*4
7 2*1,3*1,4*1,8*3,11*1
7 2*1,5*1,6*4,13*1
7 2*1,6*3,7*1,9*1,10*1
7 2*2,6*2,9*2,10*1
7 3*1,4*1,5*1,8*3,10*1
7 4*1,5*1,6*3,7*1,12*1
7 5*1,6*3,8*2,9*1
7 5*2,6*1,8*4
7 6*4,7*2,10*1
|
|