楼主: newkid

[精华] 2012感恩节最短源代码比赛newkid代码解析

[复制链接]
论坛徽章:
1
鲜花蛋
日期:2013-01-10 11:05:46
11#
发表于 2012-12-4 10:09 | 只看该作者
牛!

使用道具 举报

回复
论坛徽章:
43
ITPUB9周年纪念徽章
日期:2012-09-28 16:17:24马上有钱
日期:2014-06-16 17:13:52马上有对象
日期:2014-06-16 17:13:52马上加薪
日期:2014-06-16 17:13:52现任管理团队成员
日期:2014-06-17 02:21:03版主1段
日期:2014-06-17 02:21:04马上有车
日期:2014-10-24 22:35:032010数据库技术大会纪念徽章
日期:2015-04-23 10:33:192011数据库大会纪念章
日期:2015-04-23 10:33:192012数据库大会纪念章
日期:2015-04-23 10:33:19
12#
发表于 2012-12-4 18:59 | 只看该作者

使用道具 举报

回复
论坛徽章:
27
ITPUB官方微博粉丝徽章
日期:2011-08-17 10:35:36托尼托尼·乔巴
日期:2017-10-25 16:45:57秀才
日期:2017-04-05 13:18:06秀才
日期:2017-03-02 10:35:322016猴年福章
日期:2016-02-23 09:58:342016猴年福章
日期:2016-02-18 09:31:302015年新春福章
日期:2015-03-06 11:57:312014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:07:31
13#
发表于 2012-12-4 22:23 | 只看该作者
太牛了!求签名

使用道具 举报

回复
论坛徽章:
22
ITPUB十周年纪念徽章
日期:2011-11-01 16:21:152014年世界杯参赛球队: 比利时
日期:2014-06-15 20:40:142014年世界杯参赛球队: 科特迪瓦
日期:2014-06-30 19:29:262014年世界杯参赛球队:西班牙
日期:2014-07-08 21:49:56ITPUB元老
日期:2014-08-04 21:10:48优秀写手
日期:2014-09-24 06:00:13itpub13周年纪念徽章
日期:2014-10-03 10:51:25itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50itpub13周年纪念徽章
日期:2014-10-08 15:16:50
14#
发表于 2012-12-4 22:36 | 只看该作者
只能膜拜下了!!

使用道具 举报

回复
论坛徽章:
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
15#
 楼主| 发表于 2012-12-4 23:11 | 只看该作者
〇〇 发表于 2012-12-4 09:14
有个疑问:neighbours的用途是在递归过程中确保新加入的第N个方格和已有的N-1个方格中的至少一个相邻
这种 ...

怎么不相邻?B的右边不就是b? 按我的递归算法,这个形状构成的顺序是:b(右上)->b(右)->B(中)
每次加入的都和前一个相邻。

使用道具 举报

回复
论坛徽章:
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
16#
发表于 2012-12-5 06:41 | 只看该作者
newkid 发表于 2012-12-4 23:11
怎么不相邻?B的右边不就是b? 按我的递归算法,这个形状构成的顺序是:b(右上)->b(右)->B(中)
每次加入的 ...

那这个
aba
aBb
aaa
怎么又是从上中/中/右中?路线不一样?

使用道具 举报

回复
论坛徽章:
18
奥运会纪念徽章:沙滩排球
日期:2012-06-15 18:46:552015年新春福章
日期:2015-03-06 11:58:39慢羊羊
日期:2015-03-04 14:53:33马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08优秀写手
日期:2014-01-24 06:00:15三菱
日期:2013-08-21 16:52:31奔驰
日期:2013-07-30 17:57:36比亚迪
日期:2013-07-30 17:57:36Jeep
日期:2013-07-30 17:57:36
17#
发表于 2012-12-5 18:02 | 只看该作者
膜拜大神。。。

使用道具 举报

回复
论坛徽章:
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
18#
 楼主| 发表于 2012-12-5 23:01 | 只看该作者
〇〇 发表于 2012-12-5 06:41
那这个
aba
aBb

你理解的“路线”到底是怎样的?每个形状不一样,“路线”当然不一样!
不变的是递归的规则,每次加入的新方格都和前面相邻。不管哪个方向都可以加入。

使用道具 举报

回复
论坛徽章:
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
19#
 楼主| 发表于 2012-12-5 23:37 | 只看该作者
新加入的递归条件可以进一步提升效率

VAR N NUMBER;
EXEC :N:=8;

旧方法:
WITH blocks AS ( ----- 构造25个点坐标
SELECT TRUNC((LEVEL-1)/:N) X  ---- 行号从0到4
      ,MOD(LEVEL-1,:N) Y      ---- 列号从0到4
      ,LEVEL num             ----- 格子编号
      ,POWER(2,:N*:N-LEVEL) ID  ----- 每个格子的二进制编码,编号1作为最高位,25作为最低位,这是排序要求的
  FROM DUAL
CONNECT BY LEVEL<=:N*:N
)
,neighbours AS ( ---- 找出所有方格及其相邻的方格ID
SELECT c1.id id1
      ,SUM(c2.id) id2
      ,c1.num
  FROM blocks c1,blocks c2
WHERE ABS(c1.X-c2.X)+ABS(c1.Y-c2.Y)=1 ---- 两个方格相邻的条件
       AND c1.x+c1.y<:N  
       AND c2.x+c2.y<:N
GROUP BY c1.id,c1.num   
)
,T(cnt,id_sum,shape_val) AS ( ---- 用递归的方法生成所有位置的所有形状
SELECT 1,ID,num FROM blocks WHERE x=0 ---- 从行坐标轴上的点开始递归
UNION ALL
SELECT cnt+1,id_sum+n.id1,t.shape_val+n.num
  FROM T,neighbours n  ---- 逐渐加入其他方格
WHERE BITAND(T.id_sum,n.ID1)=0 AND BITAND(T.id_sum,n.ID2)>0 ---- 加入的条件是:该方格本身未被包含,而其邻居则已被包含
       AND cnt<:N  ---- 到达N个方格就停止
)
,all_shapes AS (
    SELECT DISTINCT id_sum,shape_val ---- 去除结果中的重复数据
      FROM T
     WHERE cnt=:N
           AND BITAND(id_sum,(SELECT SUM(id) FROM blocks WHERE y=0))>0
)
SELECT COUNT(*) FROM all_shapes;

  COUNT(*)
----------
      2725

Elapsed: 00:00:31.74

新方法:如果递归过程中发现没有希望接触到Y轴,则放弃该路径
WITH blocks AS (
SELECT TRUNC((LEVEL-1)/:N) X
      ,MOD(LEVEL-1,:N) Y   
      ,LEVEL num            
      ,POWER(2,:N*:N-LEVEL) ID
  FROM DUAL
CONNECT BY LEVEL<=:N*:N
)
,neighbours AS (
SELECT c1.id id1
      ,SUM(c2.id) id2
      ,c1.num
      ,c1.y     ---------- 为新递归条件服务
  FROM blocks c1,blocks c2
WHERE ABS(c1.X-c2.X)+ABS(c1.Y-c2.Y)=1
       AND c1.x+c1.y<:N  
       AND c2.x+c2.y<:N
GROUP BY c1.id,c1.num,c1.y
)
,T(cnt,id_sum,shape_val,min_y) AS (
SELECT 1,ID,num,y FROM blocks WHERE x=0
UNION ALL
SELECT cnt+1,id_sum+n.id1,t.shape_val+n.num,LEAST(t.min_y,n.y)  ----- min_y: 形状中最接近Y轴的点
  FROM T,neighbours n  
WHERE BITAND(T.id_sum,n.ID1)=0 AND BITAND(T.id_sum,n.ID2)>0
       AND t.min_y+t.cnt<=:N -------- 新条件:剩下方块的个数全部往Y轴方向凑,必须能够接触到Y轴
       AND cnt<:N  
)
,all_shapes AS (
    SELECT DISTINCT id_sum,shape_val ---- 去除结果中的重复数据
      FROM T
     WHERE cnt=:N
           AND BITAND(id_sum,(SELECT SUM(id) FROM blocks WHERE y=0))>0
)
SELECT COUNT(*) FROM  all_shapes;

  COUNT(*)
----------
      2725

Elapsed: 00:00:16.10

中间结果T从80多万下降为40多万。重复的还是太多,此时用PLSQL应该占优。

使用道具 举报

回复
论坛徽章:
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
20#
发表于 2012-12-6 06:51 | 只看该作者
newkid 发表于 2012-12-5 23:01
你理解的“路线”到底是怎样的?每个形状不一样,“路线”当然不一样!
不变的是递归的规则,每次加入的 ...

我理解为只有后加入的点数比已有的大,看来我错了

使用道具 举报

回复

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

本版积分规则 发表回复

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