|
|
原帖由 tree_new_bee 于 2011-1-6 19:24 发表 ![]()
实际上上面的算法与111#google到的算法似乎是一样的。
with t0 as (select 23 num from dual)
,t(r, n, a,q,p, path) as (
select 1, num, trunc(sqrt(num)),1, trunc(sqrt(num)), cast(',' as varchar2(4000)) from t0 where trunc(sqrt(num))sqrt(num)
union all
select r+1,n,
trunc(q*(sqrt(n)+p)/(n-p*p)), --a'
(n-p*p)/q, --q'
(n-p*p)/q * trunc(q*(sqrt(n)+p)/(n-p*p)) - p, -- q'*a'-p
path || p||'/'||q||','
from t where instr(path,','||p||'/'||q ||',')=0
)
select r,n,a,q,p, path, length(translate(path, ','||path, ','))-1 len from t
R N A Q P PATH LEN
---------- ---------- ---------- ---------- ---------- -------------------------------------------------------------------------------- ----------
1 23 4 1 4 , 0
2 23 1 7 3 ,4/1, 1
3 23 3 2 3 ,4/1,3/7, 2
4 23 1 7 4 ,4/1,3/7,3/2, 3
5 23 8 1 4 ,4/1,3/7,3/2,4/7, 4
昨天我还给根号加上系数,其实B恒为1, 我的写法简化后就和你一样了:
WITH n AS (SELECT LEVEL N FROM DUAL WHERE MOD(SQRT(LEVEL),1)>0 CONNECT BY LEVEL<=10000)
,t(A,C,D,STR,N) AS (
SELECT TRUNC(SQRT(N)),TRUNC(SQRT(N)),1,CAST('~' AS VARCHAR2(4000)),N FROM n
UNION ALL
SELECT TRUNC((D*SQRT(N)+D*C)/(N - C*C))
,(TRUNC((D*SQRT(N)+D*C)/(N - C*C))*(N - C*C) - D*C )/D
,(N - C*C)/D
,STR||C||','||D||'~'
,N
FROM t
WHERE INSTR(STR,'~'||C||','||D||'~')=0
) CYCLE C,D,N SET cycle_flag TO 'Y' DEFAULT 'N'
SELECT COUNT(*)
FROM (SELECT N,SUBSTR(STR, INSTR(STR,'~'||C||','||D||'~')+1) AS STR
FROM T
WHERE INSTR(STR,'~'||C||','||D||'~')>0
)
WHERE MOD(LENGTH(STR)-LENGTH(REPLACE(STR,'~')),2)=1
;
COUNT(*)
----------
1322
Elapsed: 00:00:10.95 |
|