|
奥迪已转。
顺便贴个优化过的15题,两次递归还是有好处的,现在不到1秒。同样的人数按霹雳哥写法大约4秒。
WITH all_pairs AS
(SELECT N1,N2,CASE WHEN CEIL(N1/2)=CEIL(N2/2) AND N2/2<=:P THEN 1 ELSE 0 END AS SAME_SCHOOL
,BIT1+BIT2 bits
FROM (SELECT LEVEL N1,POWER(2,LEVEL-1) BIT1 FROM DUAL CONNECT BY LEVEL<=:N)
,(SELECT LEVEL N2,POWER(2,LEVEL-1) BIT2 FROM DUAL CONNECT BY LEVEL<=:N)
WHERE N1<N2
)
,same_pairs as (SELECT * FROM all_pairs WHERE SAME_SCHOOL=1)
,same_comb(s,bits,cnt,last_n1) AS (
SELECT CAST(N1||','||N2 AS VARCHAR2(100)),bits,1,N1
FROM same_pairs
UNION ALL
SELECT s||'|'||N1||','||N2,same_comb.bits+same_pairs.bits,cnt+1,same_pairs.N1
FROM same_comb,same_pairs
WHERE N1>LAST_N1 AND CNT<:k
)
,comb(s,bits,cnt,last_n1,last_flag) AS (
SELECT CAST(s AS VARCHAR2(100)),bits,cnt,last_n1,1
FROM same_comb WHERE cnt=:k
UNION ALL
SELECT s||'|'||N1||','||N2,comb.bits+all_pairs.bits,cnt+1,all_pairs.N1,all_pairs.same_school
FROM comb,all_pairs
WHERE CNT<:N/2
AND BITAND(comb.bits,all_pairs.bits)=0
AND (last_flag=all_pairs.same_school AND N1>LAST_N1
OR last_flag=1 AND all_pairs.same_school=0
)
)
SELECT COUNT(*) FROM comb WHERE cnt=:N/2 ;
|
|