楼主: newkid

[精华] 发现一位专门用SQL解各种谜题的高人!

[复制链接]
论坛徽章:
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
81#
 楼主| 发表于 2012-8-1 22:57 | 只看该作者
udfrog 发表于 2012-8-1 22:11
其实进行更好的数学建模是第一步,比如1楼时候的exchange 1 dollar题目,所谓的最直接了当的做法,把1分硬币 ...

1分是特例,这里只是为了展示其原理。
其实这道题有更好的递归解法,可以算几百块的分解方法。你想想看?

使用道具 举报

回复
论坛徽章:
95
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
82#
发表于 2012-8-1 23:04 | 只看该作者
newkid 发表于 2012-8-1 22:57
1分是特例,这里只是为了展示其原理。
其实这道题有更好的递归解法,可以算几百块的分解方法。你想想看? ...

morning,nk,好的,明天我想想,睡了。。

使用道具 举报

回复
论坛徽章:
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
83#
 楼主| 发表于 2012-8-1 23:06 | 只看该作者
udfrog 发表于 2012-8-1 23:04
morning,nk,好的,明天我想想,睡了。。

别睡,新的puzzleup出来了,等会翻译。

使用道具 举报

回复
论坛徽章:
95
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
84#
发表于 2012-8-2 10:42 | 只看该作者
newkid 发表于 2012-8-1 22:57
1分是特例,这里只是为了展示其原理。
其实这道题有更好的递归解法,可以算几百块的分解方法。你想想看? ...

郁闷,以后睡前再也不合计问题了。不到5点就醒了,满脑子都是硬币。。。你所说的递归是这样的么?
  1. with t as (
  2. select (rownum-1)*50 val, 50 id from dual connect by rownum <=3 union all
  3. select (rownum-1)*25 val, 25 id from dual connect by rownum <=5 union all
  4. select (rownum-1)*10 val, 10 id from dual connect by rownum <=11 union all
  5. select (rownum-1)*5 val, 5 id from dual connect by rownum <=21),
  6. tmp1 as (
  7. select        connect_by_root(val) + val val, id
  8. from        t
  9. where        id=25
  10. start with id=50
  11. connect by prior id>id and prior val<=100-val),
  12. tmp2 as (
  13. select        connect_by_root(val) + val val, id
  14. from        (select * from t where id<=10 union all select * from tmp1)
  15. where        id=10
  16. start with id=25
  17. connect by prior id>id and prior val<=100-val),
  18. tmp3 as (
  19. select        connect_by_root(val) + val val, id
  20. from        (select * from t where id<=5 union all select * from tmp2)
  21. where        id=5
  22. start with id=10
  23. connect by prior id>id and prior val<=100-val)
  24. select count(*) from tmp3;
复制代码

使用道具 举报

回复
论坛徽章:
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
85#
 楼主| 发表于 2012-8-2 11:18 | 只看该作者
udfrog 发表于 2012-8-2 10:42
郁闷,以后睡前再也不合计问题了。不到5点就醒了,满脑子都是硬币。。。你所说的递归是这样的么?

不是,我说的是逐渐增加硬币种类的做法。
只有1分:很容易得到0-100的组合数。
增加1个2分,2个2分,3个2分,... 直至50个。只需在前面基础上做加法,这样你得到了硬币种类<=2的所有组合数。
再增加5分硬币,同样道理。
用PLSQL很好做,SQL也可以试试。

使用道具 举报

回复
论坛徽章:
95
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
86#
发表于 2012-8-2 11:38 | 只看该作者
newkid 发表于 2012-8-2 11:18
不是,我说的是逐渐增加硬币种类的做法。
只有1分:很容易得到0-100的组合数。
增加1个2分,2个2分,3个 ...

没错,我躺着的时候就是这么合计的,我也觉得plsql更好而且效率应该更高,不过这个就是我用这个思想实现的sql写法,很奇怪的是,我在测试change 10dollar的性能时,会跑不出来。等弄完puzzleup那个题,我再看看

使用道具 举报

回复
论坛徽章:
95
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
87#
发表于 2012-8-2 16:36 | 只看该作者
  1. declare
  2. cnt        int:=0;
  3. r        int:=0;
  4. C        int:=&how_much_dollar_to_change;
  5. begin
  6.         for i in 0 .. 2*C loop
  7.                 for j in 0 .. 4*C loop
  8.                         for k in 0 .. 10*C loop
  9.                                 exit when i*50+j*25+k*10>100*C;
  10.                                 r:=100*C-(i*50+j*25+k*10);
  11.                                 cnt:=cnt+r/5+1;
  12.                         end loop;
  13.                 end loop;
  14.         end loop;
  15.         dbms_output.put_line(cnt);
  16. end;
  17. /
复制代码
mark一下,这个代码兑换100dollar要6秒

使用道具 举报

回复
求职 : 数据库管理员
论坛徽章:
1
优秀写手
日期:2014-10-30 06:00:12
88#
发表于 2012-8-2 17:19 | 只看该作者
牛人

使用道具 举报

回复
论坛徽章:
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
89#
 楼主| 发表于 2012-8-3 00:09 | 只看该作者
凑合着看吧,时间太久了也没有注释,我自己都看不懂了(悲剧啊!)当时还想到一个改进的思路,忘记写下来现在也想不起来了。下周有空再看看吧。

DECLARE
   TYPE t_num IS TABLE OF NUMBER;
   lv_coins t_num := t_num(1,2,5,10,20,50,100,200);
   lv_limit NUMBER := 1000;  --- 10 dollars
   TYPE t_num2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
   lv_cnt   t_num2;
   lv_cnt2  t_num2;
   lv_sum NUMBER ;
   lv_ptr NUMBER;
BEGIN
   lv_cnt(0):=1;
   
   FOR i IN 1..lv_coins.COUNT LOOP
       lv_sum := lv_coins(i);
       lv_cnt2:=lv_cnt;
       WHILE lv_sum<=lv_limit LOOP
             lv_ptr := 0;
             WHILE lv_ptr IS NOT NULL LOOP
                   EXIT WHEN lv_ptr+lv_sum>lv_limit;
                   IF NOT lv_cnt.EXISTS(lv_ptr+lv_sum) THEN
                      lv_cnt(lv_ptr+lv_sum):= lv_cnt2(lv_ptr);
                   ELSE
                      lv_cnt(lv_ptr+lv_sum):= lv_cnt(lv_ptr+lv_sum)+lv_cnt2(lv_ptr);
                   END IF;
                   lv_ptr := lv_cnt2.NEXT(lv_ptr);
             END LOOP;
             lv_sum := lv_sum + lv_coins(i);
       END LOOP;
   END LOOP;
   DBMS_OUTPUT.PUT_LINE(lv_cnt(lv_limit));
END;
/

使用道具 举报

回复
论坛徽章:
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
90#
发表于 2012-8-13 07:36 | 只看该作者

使用道具 举报

回复

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

本版积分规则 发表回复

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