|
|
修改后的SQL能出来了虽然还是很慢:
WITH n AS (SELECT LEVEL N FROM DUAL WHERE MOD(SQRT(LEVEL),1)>0 CONNECT BY LEVEL<=10000)
,t(A,B,C,D,STR,GCD,N) AS (
SELECT TRUNC(SQRT(N)),1,TRUNC(SQRT(N)),1,CAST('~' AS VARCHAR2(4000)),0,N FROM n
UNION ALL
SELECT CASE WHEN GCD=0 THEN TRUNC((D*B*SQRT(N)+D*B*C)/(B*B*N - C*C)) ELSE A END
,CASE WHEN GCD=0 THEN D*B
WHEN MOD(B,GCD)=0 AND MOD(C,GCD)=0 AND MOD(D,GCD)=0 THEN B/GCD
ELSE B
END
,CASE WHEN GCD=0 THEN TRUNC((D*B*SQRT(N)+D*B*C)/(B*B*N - C*C))*(B*B*N - C*C) - D*C
WHEN MOD(B,GCD)=0 AND MOD(C,GCD)=0 AND MOD(D,GCD)=0 THEN C/GCD
ELSE C
END
,CASE WHEN GCD=0 THEN B*B*N - C*C
WHEN MOD(B,GCD)=0 AND MOD(C,GCD)=0 AND MOD(D,GCD)=0 THEN D/GCD
ELSE D
END
,CASE WHEN GCD=0 THEN STR||A||','||B||','||C||','||D||'~' ELSE STR END
,CASE WHEN GCD=0 THEN D*B ELSE 0 END
,N
FROM t
WHERE INSTR(STR,'~'||A||','||B||','||C||','||D||'~')=0
) CYCLE A,B,C,D,GCD,N SET cycle_flag TO 'Y' DEFAULT 'N'
SELECT COUNT(*)
FROM (SELECT N,SUBSTR(STR, INSTR(STR,'~'||A||','||B||','||C||','||D||'~')+1) AS STR
FROM T
WHERE INSTR(STR,'~'||A||','||B||','||C||','||D||'~')>0
)
WHERE MOD(LENGTH(STR)-LENGTH(REPLACE(STR,'~')),2)=1
;
COUNT(*)
----------
1322
Elapsed: 00:00:56.89
GOOGLE的算法你慢慢玩吧!为什么有个迭代次数 r<=50? |
|