楼主: newkid

[每日一题] puzzleup 2018

[复制链接]
论坛徽章:
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
351#
 楼主| 发表于 2018-12-9 09:40 | 只看该作者
既然数学哥也同意了,那就没问题:

VAR M NUMBER;
VAR N NUMBER;
EXEC :M :=3;
EXEC :N :=3;

With d as ( -------所有点
select x,y,row_number() over(order by x,y) id
  from (select level-1 x from dual connect by level<=:M+1)
      ,(select level-1 y from dual connect by level<=:N+1)
)
,e as (------所有边
select rownum id
     , power(2,rownum) eb -------每条边用一位二进制表示
     , ee.*
from (SELECT  d1.x x1,d1.y y1,d2.x x2,d2.y y2
         FROM d d1,d d2
        WHERE d1.id<d2.id and (abs(d1.x-d2.x),abs(d1.y-d2.y)) in ((0,1),(1,0))
       order by d1.x,d2.x,d1.y,d2.y
        ) ee
)
,c as (------每个格子以其最小坐标的点做代表
select power(2,d.id) id  -------每个格子用一位二进制表示
      ,sum(e.eb) eb ---------这个格子的四条边的四个二进制位
      ,d.x
      ,d.y
  from d
      ,e  ------ 构成方块的四条边
where d.x<:M and d.y<:N
      and (e.x1,e.y1,e.x2,e.y2) in
            ((d.x,d.y,d.x,d.y+1)
            ,(d.x,d.y,d.x+1,d.y)
            ,(d.x+1,d.y,d.x+1,d.y+1)
            ,(d.x,d.y+1,d.x+1,d.y+1)) ---- 四条边的端点坐标
group by d.id,d.x,d.y
)
,connects as ( -------找出所有相邻的方格
select c1.id id1,c2.id id2,c1.id+c2.id cb,c1.eb eb1,c2.eb eb2
  from c c1,c c2
where c1.id<c2.id
       and (abs(c1.x-c2.x),abs(c1.y-c2.y)) in ((0,1),(1,0))
)
,closed(cb,eb,rn) as (  --------找出所有单个的封闭区域(由若干个相邻的方格构成)
----- cb:构成区域的所有方块,eb:该区域的外轮廓  rn:用于去重复
select id,eb,1 from c
union all
select closed.cb+connects.cb-bitand(closed.cb,connects.cb) ------- BITOR加上新的方格
      ,closed.eb+decode(bitand(closed.cb,connects.id1),0,connects.eb1,connects.eb2) ------- BIT XOR加上新的轮廓,用XOR是因为区域内部的段都不能点亮,只需要外轮廓
           -2*bitand(closed.eb,decode(bitand(closed.cb,connects.id1),0,connects.eb1,connects.eb2))
      ,row_number() over(partition by closed.cb+connects.cb-bitand(closed.cb,connects.cb)  order by 1) rn ---按照区域形状去重复
  from closed,connects
where closed.rn=1
       and (bitand(closed.cb,connects.id1),bitand(closed.cb,connects.id2))
            IN ((connects.id1,0),(0,connects.id2)) --- 两个连续的方格有一个在区域中,另一个在区域外
)
,area as (select distinct cb,eb from closed)
,shapes(bits,cb,eb) as ( -----所有封闭区域的组合
select cb,cb,eb from area
union all
select shapes.bits+area.cb,area.cb, shapes.eb+area.eb-bitand(shapes.eb,area.eb) ---BITOR 拼上新轮廓
from shapes,area
where shapes.cb<area.cb and bitand(shapes.bits,area.cb)=0
)
select count(DISTINCT eb) from shapes;

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
352#
发表于 2018-12-9 18:25 | 只看该作者
Perfect!

使用道具 举报

回复
论坛徽章:
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
353#
发表于 2018-12-10 08:43 | 只看该作者
newkid 发表于 2018-12-9 09:40
既然数学哥也同意了,那就没问题:

VAR M NUMBER;

COUNT(DISTINCTEB)
-----------------
            12711

Elapsed: 00:00:00.59
SQL> EXEC :M :=4

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
SQL> /

COUNT(DISTINCTEB)
-----------------
           403352

Elapsed: 00:00:53.41
这个不用物理表还可以

使用道具 举报

回复
论坛徽章:
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
354#
 楼主| 发表于 2018-12-10 22:54 | 只看该作者
〇〇 发表于 2018-12-10 08:43
COUNT(DISTINCTEB)
-----------------
            12711

你这个算的是4*3,不是4*4。

使用道具 举报

回复
论坛徽章:
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
355#
 楼主| 发表于 2018-12-12 23:04 | 只看该作者
#20  CODE SETS

You will create code sets using A, B, C, D, E, F letters.

A set contains at least two codes.
Each letter is used exactly once by the code set.
Each code contains at least two letters.
When the order of codes in the set changes, it is still considered the same code set.
When the order of letters in a code changes, the code set is considered different.

How many different code sets can be created?

If the question were asked for A,B,C,D letters, the answer would be 12.

(AB, CD), (AB, DC), (AC, BD), (AC, DB), (AD, BC), (AD, CB), (BA, CD), (BA, DC), (CA, BD), (CA, DB), (DA, BC), (DA, CB).

你用A,B,C,D,E,F字母创建代码集。

一个集合少包含两个代码。
每个字母在集合中恰好被使用一次。
每个代码至少包含两个字母。
当集合中的代码顺序发生变化时,它仍被视为相同的代码集。
当代码中的字母顺序发生变化时,代码集会被视为不同。

总共可以创建多少个不同的代码集?


如果询问A,B,C,D字母的问题,答案将是12。

(AB,CD),(AB,DC),(AC,BD),(AC,DB),(AD,BC),(AD,CB),(BA,CD),(BA,DC),(CA ,BD),(CA,DB),(DA,BC),(DA,CB)。

--------------
这道题很弱,白送加菲猫一个章。
我记得以前就出过,懒得找了。

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
356#
发表于 2018-12-13 00:53 | 只看该作者
20#

n=4

SQL> with t as (select chr(64+level) c,power(2,level) b from dual connect by level <= 4),
  2       code(lvl,str,bsum) as (select 1,c,b from t
  3                           union all
  4                         select lvl + 1,
  5                                str||t.c,
  6                                bsum + t.b
  7                           from code,t
  8                          where bitand(bsum,t.b) = 0 ),
  9       valid_code(str,bsum) as (select str,bsum from code where lvl between 2 and 2),
10       set_code(lvl,set_str,set_sum) as (select 1,'('||str,bsum from valid_code
11                                          union all
12                                         select lvl + 1,
13                                                set_str||','||valid_code.str,
14                                                set_sum + bsum
15                                           from set_code,valid_code
16                                          where bitand(set_sum,bsum) = 0
17                                            and set_sum < 30 )    -- 2^1 + 2^2 + ... + 2^4 = 30
18  select sum(res)
19    from (
20          select lvl,count(set_str||')')/(case when lvl = 2 then 2 else 2 end) res
21            from set_code
22           where lvl >= 2
23             and set_sum = 30  
24           group by lvl
25         )
26  /
  SUM(RES)
----------
        12


n=6

SQL> with t as (select chr(64+level) c,power(2,level) b from dual connect by level <= 6),
  2       code(lvl,str,bsum) as (select 1,c,b from t
  3                           union all
  4                         select lvl + 1,
  5                                str||t.c,
  6                                bsum + t.b
  7                           from code,t
  8                          where bitand(bsum,t.b) = 0 ),
  9       valid_code(str,bsum) as (select str,bsum from code where lvl between 2 and 4),
10       set_code(lvl,set_str,set_sum) as (select 1,'('||str,bsum from valid_code
11                                          union all
12                                         select lvl + 1,
13                                                set_str||','||valid_code.str,
14                                                set_sum + bsum
15                                           from set_code,valid_code
16                                          where bitand(set_sum,bsum) = 0
17                                            and set_sum < 126 )   -- 2^1 + 2^2 + ... + 2^6 =126
18  select sum(res)
19    from (
20          select lvl,count(set_str||')')/(case when lvl = 2 then 2 else 6 end) res     -- n=6,lvl 只能是2和3,重复数就是 2!和 3!,lvl=4的不存在,因为集合中如果有4个及以上的CODE,那长度至少为8了。
21            from set_code
22           where lvl >= 2
23             and set_sum = 126
24           group by lvl
25         )
26  /
  SUM(RES)
----------
      1200

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
357#
发表于 2018-12-13 00:57 | 只看该作者
newkid 发表于 2018-12-12 23:04
#20  CODE SETS

You will create code sets using A, B, C, D, E, F letters.

随便送个章章

今年的PUZZLE又结束了,几乎都没人玩了  

使用道具 举报

回复
论坛徽章:
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
358#
 楼主| 发表于 2018-12-13 06:23 | 只看该作者
随便转了个弗兰奇。
我的写法:

EXEC :N:=6;

with c as (
select CHR(ascii('A')+level-1) as c,power(2,level-1) as id from dual connect by level<=:N
)
,codes(b,cnt,c) as (
select id,1,cast(c as varchar2(20)) from c
union all
select b+id,cnt+1,codes.c||c.c from codes,c where bitand(b,id)=0 and cnt<:N-1
)
,sets(b,c,last_code) as (
select b,cast(c as varchar2(200)),c from codes where cnt>1
union all
select sets.b+codes.b,sets.c||','||codes.c,codes.c
from sets,codes where bitand(sets.b,codes.b)=0 and sets.last_code<codes.c and codes.cnt>1
)
select COUNT(*) from sets where b=power(2,:N)-1;

使用道具 举报

回复
论坛徽章:
8
玉兔
日期:2015-11-16 10:18:00铁扇公主
日期:2015-10-27 21:47:42九尾狐狸
日期:2015-12-11 22:31:15
359#
发表于 2018-12-13 08:42 | 只看该作者
在MMA的强大攻势下,完全不堪一击

In[2]:= 6!*(1/1! + 1/2! + 1/3!)
Out[2]= 1200

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
360#
发表于 2018-12-13 09:37 | 只看该作者
newkid 发表于 2018-12-13 06:23
随便转了个弗兰奇。
我的写法:

的确,2指数应该按0算起,这样就是 2^n-1 算总和;
另外,sets.last_code<codes.c  加个排序就不重复了;
学习了!

使用道具 举报

回复

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

本版积分规则 发表回复

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