楼主: newkid

[精华] 出个SQL题:4皇后问题(新增马步问题在第7页)

[复制链接]
论坛徽章:
26
2010年世界杯参赛球队:阿根廷
日期:2010-07-15 16:49:17马上加薪
日期:2014-10-30 09:48:58马上有车
日期:2014-11-04 14:03:06马上有钱
日期:2015-01-13 10:14:512015年新春福章
日期:2015-03-04 14:51:122015年新春福章
日期:2015-03-06 11:57:31喜羊羊
日期:2015-03-16 10:05:36慢羊羊
日期:2015-06-02 11:57:03慢羊羊
日期:2015-06-17 16:43:46巨蟹座
日期:2015-10-19 10:12:48
51#
发表于 2010-8-19 10:04 | 只看该作者
-- 5X5的棋盘上摆放5个皇后,使得它们攻击不到的安全点最多(各皇后之间可以互相攻击)。
-- 答案是最多有3个安全点

with tmp1 as(select rownum as p from dual connect by rownum <= 5),
tmp2 as(select a.p as x,b.p as y, (a.p-1)*5+b.p as t from tmp1 a, tmp1 b),
tmp3 as(
select
  a.x as a_x, a.y as a_y,
  b.x as b_x, b.y as b_y,
  c.x as c_x, c.y as c_y,
  d.x as d_x, d.y as d_y,
  e.x as e_x, e.y as e_y
from tmp2 a, tmp2 b, tmp2 c, tmp2 d, tmp2 e
where  
  a.t < b.t and b.t < c.t and c.t < d.t and d.t < e.t)
--
select
  '('||a_x||','||a_y||')' as P1,
  '('||b_x||','||b_y||')' as P2,
  '('||c_x||','||c_y||')' as P3,
  '('||d_x||','||d_y||')' as P4,
  '('||e_x||','||e_y||')' as P5,
  ct
from
  (select
     b.a_x,b.b_x,b.c_x,b.d_x,b.e_x,b.a_y,b.b_y,b.c_y,b.d_y,b.e_y,
     count(*) as ct,max(count(*))over() as max_ct
  from tmp2 a, tmp3 b
  where abs(a.x-b.a_x)<>abs(a.y-b.a_y) and abs(a.x-b.b_x)<>abs(a.y-b.b_y)
    and abs(a.x-b.c_x)<>abs(a.y-b.c_y) and abs(a.x-b.d_x)<>abs(a.y-b.d_y)
    and abs(a.x-b.e_x)<>abs(a.y-b.e_y)
    and a.x not in (b.a_x,b.b_x,b.c_x,b.d_x,b.e_x)
    and a.y not in (b.a_y,b.b_y,b.c_y,b.d_y,b.e_y)
  group by b.a_x,b.b_x,b.c_x,b.d_x,b.e_x,b.a_y,b.b_y,b.c_y,b.d_y,b.e_y)
where ct = max_ct

-- Result
           P1        P2        P3        P4        P5        CT
1        (1,2)        (1,3)        (2,2)        (2,5)        (3,5)        3
2        (1,3)        (1,4)        (2,1)        (2,4)        (3,1)        3
3        (1,2)        (1,3)        (3,1)        (4,1)        (4,2)        3
4        (1,3)        (1,4)        (3,5)        (4,4)        (4,5)        3
5        (2,1)        (2,2)        (3,1)        (5,2)        (5,3)        3
6        (2,4)        (2,5)        (3,5)        (5,3)        (5,4)        3
7        (3,1)        (4,1)        (4,4)        (5,3)        (5,4)        3
8        (3,5)        (4,2)        (4,5)        (5,2)        (5,3)        3

-- 8 rows selected in 0.266 seconds

使用道具 举报

回复
论坛徽章:
32
奥运会纪念徽章:摔跤
日期:2012-08-23 11:03:05青年奥林匹克运动会-击剑
日期:2014-09-19 10:58:152014年世界杯参赛球队:巴西
日期:2014-07-07 12:19:232014年世界杯参赛球队: 瑞士
日期:2014-05-19 12:18:36马上有钱
日期:2014-04-08 12:12:232014年新春福章
日期:2014-04-04 14:20:47马上有钱
日期:2014-02-18 16:43:092014年新春福章
日期:2014-02-18 16:43:09红旗
日期:2014-02-14 15:15:55优秀写手
日期:2013-12-18 09:29:16
52#
发表于 2010-8-19 10:07 | 只看该作者
这个题不继续玩了,不知道规则。。

使用道具 举报

回复
论坛徽章:
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
53#
发表于 2010-8-19 10:20 | 只看该作者

回复 #51 szusunny 的帖子


论正确性,还是电脑算起来和验证起来快

使用道具 举报

回复
论坛徽章:
40
授权会员
日期:2009-03-04 17:06:25最佳人气徽章
日期:2013-03-19 17:24:25SQL极客
日期:2013-12-09 14:13:35优秀写手
日期:2013-12-18 09:29:09ITPUB元老
日期:2015-03-04 13:33:34白羊座
日期:2016-03-11 13:49:34乌索普
日期:2017-11-17 11:40:00
54#
发表于 2010-8-19 10:40 | 只看该作者
with chess -- 棋盘,X/Y为横竖轴,Z1/Z2为对角线,N为方便访问的值
as (select x.l as x,y.l as y,x.l+y.l as z1,x.l-y.l as z2,x.l||'#'||y.l as n
from (select level-1 l from dual connect by level <=5) x,
(select level-1 l from dual connect by level <=5)y ),
chess_5queen as -- 4个Queen的放置位置
(select  /*+ materialize */
q1.x as q1x, q1.y as q1y, q1.z1 as q1z1, q1.z2 as q1z2, q1.n as q1n,
q2.x as q2x, q2.y as q2y, q2.z1 as q2z1, q2.z2 as q2z2, q2.n as q2n,
q3.x as q3x, q3.y as q3y, q3.z1 as q3z1, q3.z2 as q3z2, q3.n as q3n,
q4.x as q4x, q4.y as q4y, q4.z1 as q4z1, q4.z2 as q4z2, q4.n as q4n,
q5.x as q5x, q5.y as q5y, q5.z1 as q5z1, q5.z2 as q5z2, q5.n as q5n
from chess q1, chess q2, chess q3, chess q4, chess q5
where q1.x <= 2 AND q1.y <= 2 /*q1.n = '0#0'*/
AND q1.x <= q2.x and q2.x <= q3.x and q3.x <= q4.x and q4.x <= q5.x --避免重复  
AND q1.n != q2.n and q1.n != q3.n and q1.n != q4.n AND q1.n != q5.n
and q2.n != q3.n and q2.n != q4.n AND q2.n != q5.n AND q3.n != q4.n
and q3.n != q5.n and q4.n != q5.n
)
select  /*+ materialize */
q1n, q2n, q3n, q4n, q5n ,count(b.n) cnt
from chess_5queen a, chess b
where (a.q1x=b.x or a.q1y=b.y or a.q1z1=b.z1 or a.q1z2=b.z2
    OR a.q2x=b.x or a.q2y=b.y or a.q2z1=b.z1 or a.q2z2=b.z2
    OR a.q3x=b.x or a.q3y=b.y or a.q3z1=b.z1 or a.q3z2=b.z2
    OR a.q4x=b.x or a.q4y=b.y or a.q4z1=b.z1 or a.q4z2=b.z2
    OR a.q5x=b.x or a.q5y=b.y or a.q5z1=b.z1 or a.q5z2=b.z2
    )
GROUP BY q1n, q2n, q3n, q4n, q5n
ORDER BY cnt

在滚猪大师的基础的上改了一下,
还可以剩3呢

使用道具 举报

回复
论坛徽章:
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
55#
发表于 2010-8-19 11:10 | 只看该作者

回复 #54 jiqing1004 的帖子

最后一个查询实体化没有意义

已选择226行。

已用时间:  00: 00: 21.96

[ 本帖最后由 〇〇 于 2010-8-19 11:11 编辑 ]

使用道具 举报

回复
论坛徽章:
40
授权会员
日期:2009-03-04 17:06:25最佳人气徽章
日期:2013-03-19 17:24:25SQL极客
日期:2013-12-09 14:13:35优秀写手
日期:2013-12-18 09:29:09ITPUB元老
日期:2015-03-04 13:33:34白羊座
日期:2016-03-11 13:49:34乌索普
日期:2017-11-17 11:40:00
56#
发表于 2010-8-19 12:27 | 只看该作者

回复 #55 〇〇 的帖子

with chess -- 棋盘,X/Y为横竖轴,Z1/Z2为对角线,N为方便访问的值
as (select x.l as x,y.l as y,x.l+y.l as z1,x.l-y.l as z2,x.l||'#'||y.l as n
from (select LEVEL-1 l from dual connect by level <=5) x,
(select LEVEL-1 l from dual connect by level <=5)y ),
chess_5queen as -- 5个Queen的放置位置
(select  /*+ materialize */
q1.x as q1x, q1.y as q1y, q1.z1 as q1z1, q1.z2 as q1z2, q1.n as q1n,
q2.x as q2x, q2.y as q2y, q2.z1 as q2z1, q2.z2 as q2z2, q2.n as q2n,
q3.x as q3x, q3.y as q3y, q3.z1 as q3z1, q3.z2 as q3z2, q3.n as q3n,
q4.x as q4x, q4.y as q4y, q4.z1 as q4z1, q4.z2 as q4z2, q4.n as q4n,
q5.x as q5x, q5.y as q5y, q5.z1 as q5z1, q5.z2 as q5z2, q5.n as q5n
from chess q1, chess q2, chess q3, chess q4, chess q5
where q1.x <= 2 AND q1.y <= 2 --避免对称
AND q1.n < q2.n and q2.n < q3.n and q3.n < q4.n and q4.n < q5.n --避免重复  
)
SELECT q1n, q2n, q3n, q4n, q5n
  FROM (SELECT q1n, q2n, q3n, q4n, q5n
              ,COUNT(b.n) cnt
              ,MIN(COUNT(b.n)) over() min_cnt
          FROM chess_5queen a, chess b
         WHERE  (a.q1x = b.x OR a.q1y = b.y OR a.q1z1 = b.z1 OR a.q1z2 = b.z2 OR  --攻击范围
               a.q2x = b.x OR a.q2y = b.y OR a.q2z1 = b.z1 OR a.q2z2 = b.z2 OR
               a.q3x = b.x OR a.q3y = b.y OR a.q3z1 = b.z1 OR a.q3z2 = b.z2 OR
               a.q4x = b.x OR a.q4y = b.y OR a.q4z1 = b.z1 OR a.q4z2 = b.z2 OR
               a.q5x = b.x OR a.q5y = b.y OR a.q5z1 = b.z1 OR a.q5z2 = b.z2)
         GROUP BY q1n, q2n, q3n, q4n, q5n)
WHERE cnt = min_cnt
ORDER BY q1n, q2n, q3n, q4n, q5n

修改了一下

使用道具 举报

回复
论坛徽章:
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
57#
发表于 2010-8-19 14:01 | 只看该作者
给51楼画了一个图

with t as(select level-1 l,trunc((level-1)/5) r,mod(level-1,5)c from dual connect by level<=25),
p as(
select 1 x,2 y from dual union all
select 1 x,3 y from dual union all
select 2 x,2 y from dual union all
select 2 x,5 y from dual union all
select 3 x,5 y from dual)
select replace(sys_connect_by_path(s,','),',')
from (select l,r,c, 'Q' s from t where l in (select (x-1)*5+(y-1) from p) union all
select l,r,c, decode(mod(l,2),0,'█',1,'  ') s from t where l not in (select (x-1)*5+(y-1) from p))
where level=5
connect by prior c=c-1 and prior r=r
;

REPLACE(SYS_CONNECT_BY_PATH(S,','),',')
----------------------------------
█QQ  █
  Q  █Q
█  █  Q
  █  █
█  █  █


[ 本帖最后由 〇〇 于 2010-8-19 14:04 编辑 ]

使用道具 举报

回复
论坛徽章:
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
58#
发表于 2010-8-19 14:21 | 只看该作者
找出不被攻击的格子
  1  with t as(select level-1 l,trunc((level-1)/5) r,mod(level-1,5)c from dual connect by level<=25),
  2  p as(
  3  select 1 x,2 y from dual union all
  4  select 1 x,3 y from dual union all
  5  select 2 x,2 y from dual union all
  6  select 2 x,5 y from dual union all
  7  select 3 x,5 y from dual)
  8  select * from t
  9  minus select * from t where r+1 in (select x from p)
10  minus select * from t where c+1 in (select y from p)
11  minus select * from t where r+1+c+1 in (select x+y from p)
12* minus select * from t where c-r in (select y-x from p)
SQL> /

         L          R          C
---------- ---------- ----------
        15          3          0
        20          4          0
        23          4          3

使用道具 举报

回复
论坛徽章:
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
59#
发表于 2010-8-19 14:27 | 只看该作者
画出被攻击的格子

with t as(select level-1 l,trunc((level-1)/5) r,mod(level-1,5)c from dual connect by level<=25),
p as(
select 1 x,2 y from dual union all
select 1 x,3 y from dual union all
select 2 x,2 y from dual union all
select 2 x,5 y from dual union all
select 3 x,5 y from dual)
q as(select * from t
minus select * from t where r+1 in (select x from p)
minus select * from t where c+1 in (select y from p)
minus select * from t where r+1+c+1 in (select x+y from p)
minus select * from t where c-r in (select y-x from p)
)
select replace(sys_connect_by_path(s,','),',')
from (select l,r,c, 'Q' s from t where l in (select (x-1)*5+(y-1) from p) union all
select l,r,c,'Ж's from t where l not in (select (x-1)*5+(y-1) from p) and l not in (select l from q) union all
select l,r,c, decode(mod(l,2),0,'█',1,'  ') s from t where l not in (select (x-1)*5+(y-1) from p) and l in (select l from q))
where level=5
connect by prior c=c-1 and prior r=r
;

REPLACE(SYS_CONNECT_BY_PATH(S,','),',')
------------------------------------------
ЖQQЖЖ
ЖQЖЖQ
ЖЖЖЖQ
  ЖЖЖЖ
█ЖЖ  Ж

使用道具 举报

回复
论坛徽章:
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
60#
 楼主| 发表于 2010-8-19 22:08 | 只看该作者
OO的画图手艺不错呀!


用我的位操作法:

WITH c1 AS (
   SELECT ROWNUM id, MOD(ROWNUM-1,5)+1 x,CEIL(ROWNUM/5) y FROM DUAL CONNECT BY ROWNUM<=25
   )
  ,cells AS (
   SELECT c1.id,c1.x,c1.y
         ,REPLACE(SYS_CONNECT_BY_PATH(CASE WHEN c1.x=c2.x OR c1.y = c2.y
                                                OR c1.x-c2.x IN (c1.y-c2.y,c2.y-c1.y)
                                           THEN '1'
                                           ELSE '0'
                                      END,',')
                 ,',') cover
     FROM c1, c1 c2
    WHERE level=25
    START WITH c2.id=1
   CONNECT BY c1.id = PRIOR c1.id AND c2.id = PRIOR c2.id+1
   )
,t1 AS (
SELECT c1.x||c1.y||'-'||c2.x||c2.y||'-'||c3.x||c3.y||'-'||c4.x||c4.y||'-'||c5.x||c5.y AS result
      ,LPAD(c1.cover+c2.cover+c3.cover+c4.cover+c5.cover,25,'0') cover
  FROM cells c1,cells c2, cells c3, cells c4, cells c5
WHERE c1.x BETWEEN 1 AND 3
       AND c1.y BETWEEN 1 AND 3
       AND c1.x <= c1.y
       AND c1.id < c2.id AND c2.id < c3.id AND c3.id < c4.id AND c4.id < c5.id
)
SELECT result,25-LENGTH(REPLACE(cover,'0')) FROM (
SELECT result,cover,RANK() OVER(ORDER BY LENGTH(REPLACE(cover,'0'))) rnk
  FROM t1
  )
WHERE rnk=1;

12-22-13-25-35      3
13-14-44-35-45      3

这两个答案也是对称的。

使用道具 举报

回复

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

本版积分规则 发表回复

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