楼主: 〇〇

Puzzleup 2013挑战赛即将开始

[复制链接]
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
61#
发表于 2013-8-16 21:40 | 只看该作者
lugionline 发表于 2013-8-16 06:55
有两个吧
x
-------------------

你写的代码呢?
题目要求找最大。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
62#
发表于 2013-8-16 21:44 | 只看该作者
〇〇 发表于 2013-8-16 16:35
利用instr的第4个参数,终于改对了
set num 20
SQL> with t as (select level-1 l from dual connect b ...

INSTR用得好,比我用REGEXP_COUNT快。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
63#
发表于 2013-8-16 23:03 | 只看该作者
52楼单个SQL的问题在于 test2, 里面有个笛卡尔积:
                      select t1.p||t2.p as num
                                       from test t1,test t2
                                      where (t1.p<>t2.p)

然后再带上三个EXISTS过滤,当然慢了。

我给你改了一下还好点,但是因为总体思路不佳,再改也好不到哪去,你要是有兴趣就按此思路自己把剩下的做完。

with tm as (select lpad(level,4,'0') lv from dual connect by level<=9999)
,test as (select lv p
                ,p1
                ,p1+p2 as p12
                ,p1+p2+p3 as p123
                ,p2+p3+p4 as p234
                ,p3+p4 as p34
                ,p4
           from (select TO_NUMBER(substr(lv,1,1)) as  p1, TO_NUMBER(substr(lv,2,1)) as  p2
                       ,TO_NUMBER( substr(lv,3,1)) as  p3, TO_NUMBER(substr(lv,4,1)) as  p4,lv  from tm)
           where p1+p2+p3+p4 in (1,4,9,16,25,36)
                 and REGEXP_COUNT(lv,0) in (0,1,2)
                 and REGEXP_COUNT(lv,1) in (0,1,2)
                 and REGEXP_COUNT(lv,2) in (0,1,2)
                 and REGEXP_COUNT(lv,3) in (0,1,2)
                 and REGEXP_COUNT(lv,4) in (0,1,2)
                 and REGEXP_COUNT(lv,5) in (0,1,2)
                 and REGEXP_COUNT(lv,6) in (0,1,2)
                 and REGEXP_COUNT(lv,7) in (0,1,2)
                 and REGEXP_COUNT(lv,8) in (0,1,2)
                 and REGEXP_COUNT(lv,9) in (0,1,2)
)
,test2 as (select num p from (select num
                                    ,substr(num,2,4) as num11
                                    ,substr(num,3,4) as num12
                                    ,substr(num,4,4) as num13
                               from (select t1.p||t2.p as num
                                       from test t1,test t2
                                      where (t1.p<>t2.p)
                                      AND t1.p234+t2.p1  IN (4,9,16,25,36)
                                      AND t1.p34+t2.p12  IN (4,9,16,25,36)
                                      AND t1.p4+t2.p123   IN (4,9,16,25,36)
                                     )
                               where REGEXP_COUNT(num,0) in (0,1,2)
                                     and REGEXP_COUNT(num,1) in (0,1,2)
                                     and REGEXP_COUNT(num,2) in (0,1,2)
                                     and REGEXP_COUNT(num,3) in (0,1,2)
                                     and REGEXP_COUNT(num,4) in (0,1,2)
                                     and REGEXP_COUNT(num,5) in (0,1,2)
                                     and REGEXP_COUNT(num,6) in (0,1,2)
                                     and REGEXP_COUNT(num,7) in (0,1,2)
                                     and REGEXP_COUNT(num,8) in (0,1,2)
                                     and REGEXP_COUNT(num,9) in (0,1,2)
                              ) a
                        --where exists (select 1 from test where p=a.num11)
                        --      and exists (select 1 from test where p=a.num12)
                        --      and exists (select 1 from test where p=a.num13)
            )
SELECT * FROM TEST2


使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
64#
发表于 2013-8-17 01:47 | 只看该作者
HelloWorld_001 发表于 2013-8-16 14:41
newkid找到的81978100367936已经是符合条件最大的了
49#说的另外个数字是14位里面最长的了。剩下的就更小了 ...

没看你代码,说说我的思路,仅供参考
平方数只可能是4/9/16/25
第一步,找出所有四个数字之和能构成这4个数的组合(需要满足每个数字最多只出现两次,考虑到排列,数量可能不会少)
第二步,用connect by nocycle来连接,条件是本记录的后三位=下一级记录的前三位,并且需要控制本记录中用过2次的数字不是下一级记录中的最后一个数字(这是为了过滤掉少数不合规的记录,以此减少无谓的连接),并且level<=17
第三步,找出满足条件的最大值,可以使用regexp_count来判断每个数字最多出现2次(当然,instr也可以

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
65#
 楼主| 发表于 2013-8-17 05:36 | 只看该作者
newkid 发表于 2013-8-16 21:44
INSTR用得好,比我用REGEXP_COUNT快。

我原来想象从满足条件的4位数中4个4个拼接会比1个1个拼快,结果不是
这个递归的收敛很快

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
66#
 楼主| 发表于 2013-8-17 05:48 | 只看该作者
〇〇 发表于 2013-8-17 05:36
我原来想象从满足条件的4位数中4个4个拼接会比1个1个拼快,结果不是
这个递归的收敛很快

10  select lv,count(*) from r group by lv order by lv;

                  LV             COUNT(*)
-------------------- --------------------
                   1                   10
                   2                  100
                   3                  990
                   4                 1194
                   5                 1332
                   6                 1481
                   7                 1640
                   8                 1865
                   9                 1034
                  10                  427
                  11                  135
                  12                   46
                  13                   18
                  14                    2

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
67#
 楼主| 发表于 2013-8-17 06:09 | 只看该作者
〇〇 发表于 2013-8-17 05:36
我原来想象从满足条件的4位数中4个4个拼接会比1个1个拼快,结果不是
这个递归的收敛很快

前面分析过,第5个数与第1个数的差绝对值,只能是0,5、7、9之一,实际第5个数只能是1-2个数候选
这样4次递归,也不过2^4=16倍,比1000多个笛卡儿少积再筛选少多了

使用道具 举报

回复
论坛徽章:
8
玉兔
日期:2015-11-16 10:18:00铁扇公主
日期:2015-10-27 21:47:42九尾狐狸
日期:2015-12-11 22:31:15
68#
发表于 2013-8-17 07:35 | 只看该作者
newkid 发表于 2013-8-16 21:40
你写的代码呢?
题目要求找最大。

哦,我看错了,还以为找最长的呢

使用道具 举报

回复
论坛徽章:
8
玉兔
日期:2015-11-16 10:18:00铁扇公主
日期:2015-10-27 21:47:42九尾狐狸
日期:2015-12-11 22:31:15
69#
发表于 2013-8-17 08:54 | 只看该作者
大家的做法肯定都差不多

with
d (n, m, c) as
(
        select 0, power(4, 0) * 3, power(4, 0) * 1 union all
        select n + 1, power(4, n + 1) * 3, power(4, n + 1) * 1 from d where n < 9
),
s (x, c, p1, p2, p3, p4, l) as
(
        select cast(d.n as varchar(max)), d.c, 0, 0, 0, d.n, 1 from d where n > 0 union all
        select s.x + cast(d.n as varchar(max)), s.c + d.c, s.p2, s.p3, s.p4, d.n, s.l + 1 from s, d
        where (d.m & (s.c + d.c)) < d.m
                and (s.l + 1 < 4 or (s.p2 + s.p3 + s.p4 + d.n) in (select n*n from d))
)
select x from
(
        select x, rank() over (order by l desc) r from s
) s where r = 1

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
70#
 楼主| 发表于 2013-8-17 09:28 | 只看该作者
lugionline 发表于 2013-8-17 08:54
大家的做法肯定都差不多

with

d.m & (s.c + d.c)) ?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表