楼主: newkid

[精华] puzzleup2012谜题,请用SQL或PLSQL解答

[复制链接]
论坛徽章:
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
221#
发表于 2012-10-18 02:17 | 只看该作者
newkid 发表于 2012-10-17 23:45
#13 Double Factored

Let's call a number "double factored" if at least one of its prime factors re ...

如果一个数,它的某个质数因子在分解的时候重复出现,则称之为“重因子”数。最小的连同四个相邻数都是“重因子”数的整数是多少?(四个相邻数只的是:前两个数,该数本身,后两个数)

如果问题问的是两个相邻数(前一个,该数本身,后一个)那么答案为 49 (48=2x2x2x2x3 , 49=7x7, 50=2x5x5)
————————————————————————————————
我觉得你翻译得有歧义,应该这样更好
如果一个数,它的某个质数因子在分解的时候重复出现,则称之为“重因子”数。如果一个正整数和它的四个邻居(两个在前,该数本身,两个在后)都是“重因子”数,那么这个数最小是多少?如果问题问的是一个正整数和它的两个邻居,那么这个数是49(48=2x2x2x2x3 , 49=7x7, 50=2x5x5).

使用道具 举报

回复
论坛徽章:
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
222#
发表于 2012-10-18 02:31 | 只看该作者
newkid 发表于 2012-10-18 01:29
13题果然在很小的范围内,用筛法一下子就求出来了。

with t as (select 4 a from dual union select 9 from dual union select 25 from dual union select 49 from dual union select 121 from dual union select 169 from dual ),
n as (select rownum r from dual connect by rownum<=250),--只在1000之内查找
i as (select distinct a*r p from t,n where a*r<=1000),
r as (select p, p-rank()over(order by p) g from i)
select min(p), max(p), count(*) from r group by g having count(*)>=5

运气真好,居然一下就找到了
844        848        5
说明846是答案

不过,由于答案超过了预设的13*13=169,所以有必要重新修改sql以验证这个答案是否真的是最终结果

使用道具 举报

回复
论坛徽章:
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
223#
发表于 2012-10-18 02:35 | 只看该作者
lastwinner 发表于 2012-10-18 02:31
with t as (select 4 a from dual union select 9 from dual union select 25 from dual union select 49 ...

with t as (select 4 a from dual union select 9 from dual union select 25 from dual union select 49 from dual union select 121 from dual union
           select 169 from dual union select 289 a from dual union select 361 from dual union select 529 from dual union select 841 from dual),
n as (select rownum r from dual connect by rownum<=250),--只在1000之内查找
i as (select distinct a*r p from t,n where a*r<=1000),
r as (select p, p-rank()over(order by p) g from i)
select min(p), max(p), count(*) from r group by g having count(*)>=5

结果还是846

使用道具 举报

回复
论坛徽章:
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
224#
发表于 2012-10-18 02:39 | 只看该作者
尝试了一下找6个的
with t as (select 4 a from dual union select 9 from dual union select 25 from dual union select 49 from dual union select 121 from dual union
           select 169 from dual union select 289 a from dual union select 361 from dual union select 529 from dual union select 841 from dual),
n as (select rownum r from dual connect by rownum<=12500),--只在1000之内查找
i as (select distinct a*r p from t,n where a*r<=50000),
r as (select p, p-rank()over(order by p) g from i)
select min(p), max(p), count(*) from r group by g having count(*)>=6
————————————————————————————————————————
结果有俩
22020        22025        6
47672        47677        6


当然,不能保证这就是最小的结果。

————————————————————————————————————————————————————
这个问题,如果用筛除,应该会效率更高,毕竟在剔除所有的质数和任意两个质数的乘积后,只需要从剩下的数中找出最小的连续N个数,就一定是满足题设要求的答案了

使用道具 举报

回复
论坛徽章:
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
225#
 楼主| 发表于 2012-10-18 02:48 | 只看该作者
呵呵,殊途同归,我是从以前的PLSQL程序改的:

DECLARE
   TYPE t_row IS TABLE OF  BINARY_INTEGER;

   V_RESULT T_row:=t_row();
   V_RESULT2 T_row:=t_row();
   
   I NUMBER DEFAULT 1;
   J NUMBER DEFAULT 0;
   C NUMBER DEFAULT 1;
   
   lv_limit NUMBER := 1e5;
   
   lv_upper1 NUMBER := SQRT(lv_limit);
   
   lv_step BINARY_INTEGER;
BEGIN
    v_result.EXTEND(lv_limit);
    v_result2.EXTEND(lv_limit);
   
    v_result.DELETE(1);
    i:=2;
    while i<=lv_upper1 loop
          lv_step := i*i;
          j := lv_step;
          while j<=lv_limit loop
                j:=j+lv_step;
                v_result2.DELETE(j);
          end loop;

          j:=i*2;
          while j<=lv_limit loop
                v_result.DELETE(j);
                j:=j+i;
          end loop;
          i := v_result.NEXT(i);
    end loop;
   
    j := v_result2.NEXT(3);
    WHILE j>0 LOOP
       IF v_result2.NEXT(j) - j >5 THEN
          DBMS_OUTPUT.PUT_LINE(j+3);
          EXIT;
       END IF;
       j := v_result2.NEXT(j);
    END LOOP;

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
226#
发表于 2012-10-18 07:53 | 只看该作者
newkid 发表于 2012-10-17 23:45
#13 Double Factored

Let's call a number "double factored" if at least one of its prime factors re ...

终于见到一个sql好懂的题了

使用道具 举报

回复
论坛徽章:
93
生肖徽章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
227#
发表于 2012-10-18 10:16 | 只看该作者
嗯,差不多
  1. with df as (
  2. select (rownum+1)*(rownum+1) df from dual connect by rownum<=20),
  3. t as (
  4. select rownum f from dual connect by rownum<=1000),
  5. tmp as (
  6. select        min(df*f) keep (dense_rank first order by df*f) r, row_number() over (order by df*f) rn
  7. from        df, t
  8. group by df*f)
  9. select        min(a.r)-2
  10. from        tmp a, tmp b
  11. where        a.r=b.r+4
  12. and        a.rn=b.rn+4;
复制代码

使用道具 举报

回复
论坛徽章:
93
生肖徽章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
228#
发表于 2012-10-18 13:53 | 只看该作者
lastwinner 发表于 2012-10-18 02:39
尝试了一下找6个的
with t as (select 4 a from dual union select 9 from dual union select 25 from dua ...

“这个问题,如果用筛除,应该会效率更高,毕竟在剔除所有的质数和任意两个质数的乘积后”
这是不够的,质数与合数的乘积仍然未必满足。
而且,这样的筛除操作是:无限集a-无限集b=无限集c,再从c里面选最小的,这必须出不来结果。

使用道具 举报

回复
论坛徽章:
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
229#
发表于 2012-10-19 00:53 | 只看该作者
udfrog 发表于 2012-10-18 13:53
“这个问题,如果用筛除,应该会效率更高,毕竟在剔除所有的质数和任意两个质数的乘积后”
这是不够的, ...

嗯,应该是若干质数的乘积,我疏忽了

使用道具 举报

回复
论坛徽章:
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
230#
 楼主| 发表于 2012-10-19 02:32 | 只看该作者
本帖最后由 newkid 于 2012-10-20 03:17 编辑

我的筛法有两个筛子,一个找素数一个找平方数,所以是不会遗漏的。

再优化一下,第二个筛眼足够大时没有必要往前挖:

DECLARE
   TYPE t_row IS TABLE OF  BINARY_INTEGER;

   V_RESULT T_row:=t_row();
   V_RESULT2 T_row:=t_row();
   
   I NUMBER DEFAULT 1;
   J NUMBER DEFAULT 0;
   
   lv_limit NUMBER := 2e6;
   
   lv_upper1 NUMBER := SQRT(lv_limit);
   
   lv_step BINARY_INTEGER;
   lv_found NUMBER := 0;
   lv_cnt NUMBER := 8;
BEGIN
    v_result.EXTEND(lv_limit);
    v_result2.EXTEND(lv_limit);
   
    v_result.DELETE(1);
    i:=2;
    while i<=lv_upper1 loop
          lv_step := i*i;
          j := lv_step;
          while j<=lv_limit loop
                j:=j+lv_step;
                IF v_result2.EXISTS(j) THEN
                   v_result2.DELETE(j);
                   IF v_result2.NEXT(j) - v_result2.PRIOR(j) >= lv_cnt+1 THEN
                      IF v_result2.PRIOR(j)<lv_found OR lv_found=0 THEN
                         lv_found := v_result2.PRIOR(j);
                         lv_limit := lv_found;
                         lv_upper1 := LEAST(lv_upper1,lv_found);
                      END IF;
                      EXIT;
                   END IF;
                END IF;
          end loop;

          j:=i*(i-1);
          while j<=lv_limit loop
                v_result.DELETE(j);
                j:=j+i;
          end loop;
          i := v_result.NEXT(i);
    end loop;
   
    IF lv_found>0 THEN
       DBMS_OUTPUT.PUT_LINE(lv_found+1);
    END IF;
END;
/

1092747
这是二百万内找连续8个的。

使用道具 举报

回复

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

本版积分规则 发表回复

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