|
本帖最后由 tree_new_bee 于 2012-2-17 23:10 编辑
81,82,83是一个系列的, 只是难度越来越大。
Q81本身很简单, 就是处理这个文件麻烦点,不过处理好了,后两道题就不用费神了。
其实要是不用SQL, 而是用excel来做的话,几分钟就能搞定。
对文件的读取,依然沿用以前Q67的外部表的方法, 把一整行读到表中的一个长字段中, 然后在语句中去处理。 (SQL*LOADER用的不熟,否则也许可以直接读成行列?)
- create table euler_q81(
- rn number,
- line varchar2 (400)
- )
- ORGANIZATION EXTERNAL (
- TYPE ORACLE_LOADER
- DEFAULT DIRECTORY euler_dir
- ACCESS PARAMETERS
- (
- records delimited by '\r\n'
- badfile euler_dir:'triangle%a_%p.bad'
- logfile euler_dir:'triangle%a_%p.log'
- fields terminated by '\r\n'
- (rn RECNUM,
- line char(400))
- )
- LOCATION ('matrix81.txt')
- );
复制代码
计算很简单, 每个单元加上左或上的单元中的较小值即可。 用MODEL语句最方便。- with td as (select level c from dual connect by level<=80)
- , t as (select rn r, c,
- to_number(substr(line,
- case when c=1 then 1 else instr(line,',',1, c-1)+1 end,
- case when c=1 then instr(line,',',1, c) -1
- when c=80 then 10
- else instr(line,',',1, c) - instr(line,',',1, c-1)-1 end
- )) num
- from euler_q81 t, td)
- -- select r,c, to_number(num) num from t;
- ,t2 as (SELECT r,c,num
- FROM t
- MODEL
- DIMENSION BY (r,c)
- MEASURES (num)
- RULES update
- (
- update num[any, any] order by r , c =
- case when cv(r)=1 and cv(c)=1 then num[cv(r),cv(c)]
- when cv(r) = 1 and cv(c)>1 then num[cv(r),cv(c)] + num[cv(r), cv(c)-1]
- when cv(c) = 1 and cv(r)>1 then num[cv(r),cv(c)] + num[cv(r)-1, cv(c) ]
- else num[cv(r),cv(c)] + least(num[cv(r)-1,cv(c)], num[cv(r), cv(c)-1])
- end
- ) order by r , c)
- select * from t2 where r=80 and c=80
复制代码 R C NUM
---------- ---------- ----------
80 80 427337
Executed in 0.093 seconds
|
|