楼主: newkid

[每日一题] puzzleup 2021

[复制链接]
论坛徽章:
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
241#
发表于 2021-10-17 09:07 来自手机 | 只看该作者
学习了

使用道具 举报

回复
论坛徽章:
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
242#
发表于 2021-10-17 11:05 | 只看该作者
newkid 发表于 2021-10-17 07:36
给猫猫转了个章。答案至少为十。反证法:假设九能满足。划走三行之后,剩下的棋子如果不超过三个,则不满足 ...

对的 32400 ,前回复了这个数字,贴子被吞了

使用道具 举报

回复
论坛徽章:
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
243#
发表于 2021-10-17 11:29 | 只看该作者

SQL>   with
  2      function f_check (p_nlist in varchar2)   --这个函数主要是对主查询的每一个结果检查删除3行删除3列后是否还要元素存在,有就是一个解
  3    return int
  4    is
  5      type r_rec is record( n int,       --主查询是一个对1-36的整数串,x,y坐标也存储起来,方便后面删除判断
  6                            x int,
  7                            y int);
  8  
  9      type t_rec is table of r_rec index by pls_integer;
10      l_rec t_rec;
11      l_tmp t_rec;
12  
13      l_cnt   int := 0;
14      l_t_cnt int := -1;
15  
16    begin
17  
18      select n,            --将主查询的每一个结果转换成一个10个元素的集合
19             ceil(n/6),
20             mod(n-1,6)+1
21        bulk collect into l_rec
22        from (
23              select regexp_substr(p_nlist,'[^,]+',1,level) n
24                from dual
25               connect by level <= regexp_count(p_nlist,',')+1
26             );
27  
28       for rec in ( with t as (  
29                              select substr(sys_connect_by_path(n,','),2) rc              
30                                from (select level n from dual connect by level<=6)
31                               where level = 3
32                              connect by prior n < n   
33                              )
34                              select a.rc x_rc,b.rc y_rc   --这个隐式游标就是删除3个行和3个列的行列的全部组合 20*20=400个
35                                from t a,t b   ) loop
36  
37         l_tmp := l_rec;  --因为对主查询的每一个结果的判断,是用集合的方式删除元素,所以要先赋给一个临时对象
38  
39         for i in l_tmp.first..l_tmp.last loop  --先删行
40           if l_tmp.exists(i)=TRUE and instr(rec.x_rc,l_tmp(i).x) > 0 then  --元素存在,并且元素的x坐标在被删除的3个行号集合中,则删除
41             l_tmp.delete(i);
42           end if;
43         end loop;
44  
45         for i in l_tmp.first..l_tmp.last loop                             --同上,删除列
46           if l_tmp.exists(i)=TRUE and instr(rec.y_rc,l_tmp(i).y) > 0 then
47             l_tmp.delete(i);
48           end if;
49         end loop;
50  
51         if l_tmp.count > 0 then   --删完后,如果还剩余元素,就加1,删除3个行和3个列的行列的全部组合 20*20=400个,如果 l_cnt最后等于400
52           l_cnt := l_cnt + 1;     --就表明,不管你怎么删除,都至少有一个元素存在,那就是结果了
53         else
54           return 0;   --400组中的任何一组的判断,删了之后,没有任何元素剩余,那肯定就不是一个解
55         end if;
56  
57       end loop;
58  
59       select count(*)
60         into l_t_cnt    --删除3个行和3个列的行列的全部组合 20*20=400个,其实就是400,用常量代替更快
61         from (
62           with t as (
63                      select substr(sys_connect_by_path(n,','),2) rc
64                        from (select level n from dual connect by level<=6)
65                       where level = 3
66                      connect by prior n < n
67                      )
68                      select a.rc x_rc,b.rc y_rc
69                        from t a,t b
70         );
71  
72       if l_cnt=l_t_cnt then   --等于400 就返回1,是一个解
73         return 1;
74       else
75         return 0;
76       end if;
77  
78    end;
79     t(n,c,x,y) as (select level,chr(64+level),ceil(level/6),mod(level-1,6)+1 from dual connect by level<=6*6),
80     s(lvl,n,nlist,clist) as (select 1, n,cast(n as varchar2(100)),c
81                                   from t
82                                  where t.n between 1 and 6
83                                union all
84                               select lvl + 1,
85                                      b.n,
86                                      nlist||','||b.n,
87                                      clist||','||b.c
88                                 from s,t b
89                                where s.n < b.n
90                                  and (select greatest(sum(case when a.x = b.x then 1 end),  --跟第六题的差不多,不同的是,这里只用判断行和列
91                                                       sum(case when a.y = b.y then 1 end)
92                                                       )
93                                         from t a
94                                        where instr(clist||','||b.c,a.c)>0
95                                       ) <= 2  --每行每列都不多与2
96                                  and lvl < 10
97                                  and b.n between (ceil((lvl+1)/2)-1)*6 + 1 and (ceil((lvl+1)/2)-1)*6 + 6*2  --由于有的行只有一个元素,那他的范围要多一行
98                    )
99    select nlist from s where lvl = 10 and f_check(nlist)=1 and rownum <= 100  --速度比较慢,就只取前100个解吧。。。
100  /

使用道具 举报

回复
论坛徽章:
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
244#
发表于 2021-10-17 13:16 来自手机 | 只看该作者
newkid 的构造比递归快

使用道具 举报

回复
论坛徽章:
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
245#
发表于 2021-10-17 16:19 来自手机 | 只看该作者
把你们的方法结合了,很慢,用取模去掉了一些,24秒。sqlite数据库

with t6(n) as (select 1 union all select n+1 from t where n<6)
,
b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
,
b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
,
t(n,c,x,y)
as(select 1,'1',1,1 union all select n+1,cast(n+1 as varchar),n/6+1,n%6+1 from t where n<6*6)
,
s(lv,n,nlist,blist)
as(select 1,t.n,t.c,1<<(t.n-1) from t where t.n<=6
union all
select lv+1,b.n,nlist||','||c,blist+(1<<(b.n-1))
from s,t b
where lv<10 and s.n<b.n
and(blist%19<14)
and(select max(sum(case when a.x=b.x then 1 end), sum(case when a.y=b.y then 1 end))from t a
  where ((blist+(1<<(b.n-1))&(1<<(a.n-1)))>0))<=2
and b.n -lv/2*6 between 1 and 6*2
)
select * from s where lv=10 and (lv<3 or not exists(select 1 from b9 where (blist & b9.b) =0))
limit 100

使用道具 举报

回复
论坛徽章:
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
246#
发表于 2021-10-17 16:22 | 只看该作者
〇〇 发表于 2021-10-17 13:16
newkid 的构造比递归快

以前也见到过你和他都玩个这种构造,没有仔细琢磨,也学不会

使用道具 举报

回复
论坛徽章:
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
247#
发表于 2021-10-17 16:23 来自手机 | 只看该作者
想把not exists 放在递归中,似乎不对

使用道具 举报

回复
论坛徽章:
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
248#
发表于 2021-10-17 16:58 来自手机 | 只看该作者
加了and blist >=b9.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
249#
发表于 2021-10-17 19:09 来自手机 | 只看该作者
用power10代替sum,能快2倍,但最后not exist 没办法改

使用道具 举报

回复
论坛徽章:
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
250#
发表于 2021-10-17 21:40 | 只看该作者
〇〇 发表于 2021-10-17 16:19
把你们的方法结合了,很慢,用取模去掉了一些,24秒。sqlite数据库with t6(n) as (select 1 union all sele ...

sqlite 中的 << 这是什么运算,是移位运算吗?  把你写的这个能直接写个ORACLE版吗? 谢谢!

使用道具 举报

回复

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

本版积分规则 发表回复

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