首页 > 数据库 >SQL递归游戏-你厉害吗,来过5关

SQL递归游戏-你厉害吗,来过5关

时间:2022-12-19 22:33:48浏览次数:72  
标签:f1 过河 递归 union 来过 SQL path where select


5个flash的游戏地址是
​​​ http://www.sostart.com/article/view.php/765​​​ 此类游戏一般都是通过穷举或者递归之类的方法来求解,对于编成语言来说都比较简单。
这里用SQL语言的CTE递归来玩玩看。我的算法和答案如下:

 

 

 


/* 
    四个字段分别代表 羊,狼,草,人的位置,0表示河左边,1表示河右边。 
    每次都必须有人过河,因为动物和植物们都不会划船。 
*/ 
declare  @t  table ( y  bit  ,  l  bit  ,  c  bit  ,  r  bit  ,  path  varchar ( 8000 ))
insert  into  @t  select  0  ,  0  ,  0  ,  0  ,  '' 

; with  t 
as 
(
     select  *  ,  0  as  cc  from  @t  union  all 
     select  ~  y  ,  l  ,  c  ,  ~  r  ,  path  +  '人羊'  +  ltrim ( r ) +  '→'  ,  cc  +  1  from  t  where  cc <  10  and  y  =  r  and  y  &  l  &  c  =  0  and  path  not  like  '%人羊_→'  union  all 
     select  y  ,  ~  l  ,  c  ,  ~  r  ,  path  +  '人狼'  +  ltrim ( r ) +  '→'  ,  cc  +  1  from  t  where  cc <  10  and    l  =  r  and  y  &  l  &  c  =  0  and  y  <>  c  and  path  not  like  '%人狼_→'  union  all 
     select  y  ,  l  ,  ~  c  ,  ~  r  ,  path  +  '人草'  +  ltrim ( r ) +  '→'  ,  cc  +  1  from  t  where   cc  <  10  and  c  =  r  and  y  &  l  &  c  =  0  and  y  <>  l  and  path  not  like  '%人草_→'  union  all 
     select  y  ,  l  ,  c  ,  ~  r  ,  path  +  '人'  +  ltrim ( r ) +  '→'  ,  cc  +  1  from  t  where  cc  < 10  and    y  &  l  &  c  =  0  and  y  <>  c  and  y  <>  l  and  path  not  like  '%人_→' 
    
)
select  REPLACE ( REPLACE ( path  ,  '0'  ,  '过河'  ),  '1'  ,  '返回' )  as  path  from  t  where  y  & l  &  c  =  1 

/* 
人羊过河→人返回→人草过河→人羊返回→人狼过河→人返回→人羊过河→ 
人羊过河→人返回→人狼过河→人羊返回→人草过河→人返回→人羊过河→ 
*/


 




/* 

    前五个字段分别代表 左人数,左鬼数,右人数,右鬼数,船位置 
    船位置为代表在右边,代表在左边 
    当右边没有人和鬼时(gr+pr>0),不执行返回操作,递归结束 
*/ 
; with  t ( pl  ,  gl  ,  pr  ,  gr  ,  boat  ,  path )
as 
(
     select  0  ,  0  ,  3  ,  3  ,  cast ( 0  as  bit  ),  cast ( ''  as  varchar ( 8000 ))  union  all 
     select  pl  +  2  as  pl  ,  gl  ,  pr  -  2  as  pr  ,  gr  ,  ~  boat  ,  path  +  '2人过河→' 
         from  t  where  boat  =  0  and  pr  >=  2  and ( pr  -  2  >=  gr  or  pr  =  2 )  union  all 
     select  pl  +  1  ,  gl  +  1  ,  pr  -  1  ,  gr  -  1  ,  ~  boat  ,  path  +  '1人鬼过河→' 
         from  t  where  boat  =  0  and  pr  >=  1  and  gr  >=  1  and  pl  >=  gl    union  all 
     select  pl  ,  gl  +  2  ,  pr  ,  gr  -  2  ,  ~  boat  ,  path  +  '2鬼过河→' 
         from  t  where  boat  =  0  and  gr  >=  2  and ( pl  -  2  >=  gl  or  pl  =  0 )  union  all 
     select  pl  -  1  ,  gl  ,  pr  +  1  ,  gr  ,  ~  boat  ,  path  +  '1人返回→' 
         from  t  where  boat  =  1  and  pl  >=  1  and  gr  +  pr  >  0    and ( pl  -  1  >=  gl  or  pl  = 1 )  and  pr  +  1  >=  gr  union  all 
     select  pl  ,  gl  -  1  ,  pr  ,  gr  +  1  ,  ~  boat  ,  path  +  '1鬼返回→' 
         from  t  where  boat  =  1  and  gl  >=  1  and  gr  +  pr  >  0  and ( pr  -  1  >=  gr  or  pr  =  0)   union  all 
     select  pl  -  1  ,  gl  -  1  ,  pr  +  1  ,  gr  +  1  ,  ~  boat  ,  path  +  '1人鬼返回→' 
         from  t  where  boat  =  1  and  pl  >=  1  and  gl  >=  1  and  gr  +  pr  >  0  and  pr  >=  gr  and path  not  like  '%1人鬼过河→' 
)
select  path  from  t  where  pr  =  0  and  gr  =  0 

/* 
2鬼过河→鬼返回→鬼过河→鬼返回→人过河→人鬼返回→人过河→鬼返回→鬼过河→鬼返回→鬼过河→ 
2鬼过河→鬼返回→鬼过河→鬼返回→人过河→人鬼返回→人过河→鬼返回→鬼过河→人返回→人鬼过河→ 
1人鬼过河→人返回→鬼过河→鬼返回→人过河→人鬼返回→人过河→鬼返回→鬼过河→鬼返回→鬼过河→ 
1人鬼过河→人返回→鬼过河→鬼返回→人过河→人鬼返回→人过河→鬼返回→鬼过河→人返回→人鬼过河→ 
*/ 


 

 

 


/* 
第三关:一家人过河 

结果:过河的全部组合有万多中情况,其中满足s之内的有种方法 

关联的三个表a b c配合charindex函数分别可以表示出可以过河的两个人和可以返回的一个人 
当没有人可以过河则递归自动结束 
递归中的case语句可以表示当对岸有个人的时候就不需要返回 
*/ 

declare  @t  table ( name  varchar ( 8000  ),  time  int )

insert  into  @t 
select  '瘦人'  ,  1  union 
select  '小胖'  ,  3  union 
select  '姑娘'  ,  6  union 
select  '大胖'  ,  8  union 
select  '瘸子'  ,  12 

; with  t ( forword_name  ,  time  ,  path )  as ( 

     select    replace ( a  .  name  + b .  name  ,  c  .  name  ,  ''  ), b .  time  +  c  .  time  ,  a  . name  + b .  name  +  '过河→'  +  c  .  name  +  '返回→' 
         from  @t  a  ,  @t b ,  @t  c    where  a  .  time  < b .  time  and  charindex ( c  .  name  ,  a .  name  + b .  name ) >  0 
        
     union  all 
    
     select   
         case  when  len ( forword_name ) <  6  then  replace ( forword_name  +  a  .  name  + b . name  ,  c  .  name  ,  '' )  else  forword_name  +  a  .  name  + b .  name  end  , 
         case  when  len ( forword_name ) <  6  then  t  .  time  + b .  time  +  c  .  time  else  t  . time  + b .  time  end  , 
         case  when  len ( forword_name ) <  6  then  path  +  a  .  name  + b .  name  +  '过河→'  +  c  . name  +  '返回→'  else  path  +  a  .  name  + b .  name  +  '过河→'  end 
         from  @t  a  ,  @t b ,  @t  c  ,  t    where  a  .  time  < b .  time  and  charindex ( c  .  name ,  forword_name  +  a  .  name  + b .  name ) >  0 
         and  charindex ( a  .  name  ,  t  .  forword_name ) =  0  and  charindex (b .  name  ,  t  . forword_name ) =  0 
   )
   select  path  ,  time  from  t  where  len ( forword_name ) =  10    and  time  <=  30 
/* 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人小胖过河→瘦人返回→瘦人姑娘过河→ 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人小胖过河→瘦人返回→瘦人姑娘过河→ 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人小胖过河→瘦人返回→瘦人姑娘过河→ 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人小胖过河→瘦人返回→瘦人姑娘过河→ 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人小胖过河→瘦人返回→瘦人姑娘过河→ 
瘦人小胖过河→小胖返回→大胖瘸子过河→瘦人返回→瘦人姑娘过河→瘦人返回→瘦人小胖过河→ 
...共40行 
*/ 


 




/*第四关:跳马 
*/ 

declare  @t  table (p  varchar ( max  ),  x  int  ,  y  int )
insert  into  @t 
select  'p11'  ,  1  ,  1  union 
select  'p12'  ,  1  ,  2  union 
select  'p13'  ,  1  ,  3  union 
select  'p14'  ,  1  ,  4  union 
select  'p21'  ,  2  ,  1  union 
select  'p22'  ,  2  ,  2  union 
select  'p23'  ,  2  ,  3  union 
select  'p24'  ,  2  ,  4  union 
select  'p31'  ,  3  ,  1  union 
select  'p32'  ,  3  ,  2  union 
select  'p33'  ,  3  ,  3  union 
select  'p34'  ,  3  ,  4  union 
select  'p42'  ,  4  ,  2  union 
select  'p43'  ,  4  ,  3 

; with  t ( pstart  , p ,  c  ,  x  ,  y )  as 
(
     select   p , p ,  1  ,  x  ,  y  from  @t 
         union  all 
     select  t  .  pstart  ,  t  . p +  '→'  +  t_next  . p ,  c  +  1  ,  t_next  .  x  ,  t_next  .  y  from @t  t_next  ,  t  where 
        (
            ( abs ( t_next  .  x  -  t  .  x ) =  1  and  abs ( t_next  .  y  -  t  .  y ) =  2 )  or 
            ( abs ( t_next  .  x  -  t  .  x ) =  2  and  abs ( t_next  .  y  -  t  .  y ) =  1 ) )
             and ( CHARINDEX ( t_next  . p ,  t  . p) =  0  or ( c  =  14  and  t_next  . p =  t  . pstart ))
)
select p  from  t    where  c  =  15 

/* 
p43→p31→p23→p11→p32→p13→p21→p42→p34→p22→p14→p33→p12→p24→p43 
p43→p31→p12→p33→p14→p22→p34→p13→p21→p42→p23→p11→p32→p24→p43 
p43→p31→p12→p24→p32→p11→p23→p42→p34→p13→p21→p33→p14→p22→p43 
p43→p24→p32→p11→p23→p42→p21→p13→p34→p22→p14→p33→p12→p31→p43 
...共112行 
*/ 


 

 


with  t  as (
     select  17  as  f1  ,  26  as  f2  ,  20  as  f3  ,  19  as  f4  ,  31  as  f5  ,  cast ( ''  as   varchar ( 8000 ))  as  path 
         union  all  select  f1  +  8  ,  f2  +  8  ,  f3  ,  f4  ,  f5  ,  path  +  '12上→'  from  t  where f1  <  21  and  f2  <  21 
         union  all  select  f1  +  8  ,  f2  ,  f3  +  8  ,  f4  ,  f5  ,  path  +  '13上→'  from  t  where f1  <  21  and  f3  <  21 
         union  all  select  f1  +  8  ,  f2  ,  f3  ,  f4  +  8  ,  f5  ,  path  +  '14上→'  from  t  where f1  <  21  and  f4  <  21 
         union  all  select  f1  +  8  ,  f2  ,  f3  ,  f4  ,  f5  +  8  ,  path  +  '15上→'  from  t  where f1  <  21  and  f5  <  21 
         union  all  select  f1  ,  f2  +  8  ,  f3  +  8  ,  f4  ,  f5  ,  path  +  '23上→'  from  t  where f2  <  21  and  f2  <  21 
         union  all  select  f1  ,  f2  +  8  ,  f3  ,  f4  +  8  ,  f5  ,  path  +  '24上→'  from  t  where f2  <  21  and  f4  <  21 
         union  all  select  f1  ,  f2  +  8  ,  f3  ,  f4  ,  f5  +  8  ,  path  +  '25上→'  from  t  where f2  <  21  and  f5  <  21 
         union  all  select  f1  ,  f2  ,  f3  +  8  ,  f4  +  8  ,  f5  ,  path  +  '34上→'  from  t  where f3  <  21  and  f4  <  21 
         union  all  select  f1  ,  f2  ,  f3  +  8  ,  f4  ,  f5  +  8  ,  path  +  '35上→'  from  t  where f3  <  21  and  f5  <  21 
         union  all  select  f1  ,  f2  ,  f3  ,  f4  +  8  ,  f5  +  8  ,  path  +  '45上→'  from  t  where f4  <  21  and  f5  <  21 
         union  all  select  f1  -  13  ,  f2  -  13  ,  f3  ,  f4  ,  f5  ,  path  +  '12下→'  from  t  where f1  >  25  and  f2  >  25 
         union  all  select  f1  -  13  ,  f2  ,  f3  -  13  ,  f4  ,  f5  ,  path  +  '13下→'  from  t  where f1  >  25  and  f3  >  25 
         union  all  select  f1  -  13  ,  f2  ,  f3  ,  f4  -  13  ,  f5  ,  path  +  '14下→'  from  t  where f1  >  25  and  f4  >  25 
         union  all  select  f1  -  13  ,  f2  ,  f3  ,  f4  ,  f5  -  13  ,  path  +  '15下→'  from  t  where f1  >  25  and  f5  >  25 
         union  all  select  f1  ,  f2  -  13  ,  f3  -  13  ,  f4  ,  f5  ,  path  +  '23下→'  from  t  where f2  >  25  and  f2  >  25 
         union  all  select  f1  ,  f2  -  13  ,  f3  ,  f4  -  13  ,  f5  ,  path  +  '24下→'  from  t  where f2  >  25  and  f4  >  25 
         union  all  select  f1  ,  f2  -  13  ,  f3  ,  f4  ,  f5  -  13  ,  path  +  '25下→'  from  t  where f2  >  25  and  f5  >  25 
         union  all  select  f1  ,  f2  ,  f3  -  13  ,  f4  -  13  ,  f5  ,  path  +  '34下→'  from  t  where f3  >  25  and  f4  >  25 
         union  all  select  f1  ,  f2  ,  f3  -  13  ,  f4  ,  f5  -  13  ,  path  +  '35下→'  from  t  where f3  >  25  and  f5  >  25 
         union  all  select  f1  ,  f2  ,  f3  ,  f4  -  13  ,  f5  -  13  ,  path  +  '45下→'  from  t  where f4  >  25  and  f5  >  25 
        
         union  all  select  f1  +  8  ,  f2  +  8  ,  f3  ,  f4  ,  f5  ,  path  +  '12上→'  from  t  where f1  <  21  and  f2  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  +  8  ,  f2  ,  f3  +  8  ,  f4  ,  f5  ,  path  +  '13上→'  from  t  where f1  <  21  and  f3  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  +  8  ,  f2  ,  f3  ,  f4  +  8  ,  f5  ,  path  +  '14上→'  from  t  where f1  <  21  and  f4  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  +  8  ,  f2  ,  f3  ,  f4  ,  f5  +  8  ,  path  +  '15上→'  from  t  where f1  <  21  and  f5  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  +  8  ,  f3  +  8  ,  f4  ,  f5  ,  path  +  '23上→'  from  t  where f2  <  21  and  f2  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  +  8  ,  f3  ,  f4  +  8  ,  f5  ,  path  +  '24上→'  from  t  where f2  <  21  and  f4  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  +  8  ,  f3  ,  f4  ,  f5  +  8  ,  path  +  '25上→'  from  t  where f2  <  21  and  f5  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  ,  f3  +  8  ,  f4  +  8  ,  f5  ,  path  +  '34上→'  from  t  where f3  <  21  and  f4  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  ,  f3  +  8  ,  f4  ,  f5  +  8  ,  path  +  '35上→'  from  t  where f3  <  21  and  f5  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
         union  all  select  f1  ,  f2  ,  f3  ,  f4  +  8  ,  f5  +  8  ,  path  +  '45上→'  from  t  where f4  <  21  and  f5  <  23  and  f3  between  21  and  25  and  f4  between  21  and  25  and  f5  between 21  and  25 
)

select  path  from  t 
where  f1  between  21  and  25 
and  f2  between  21  and  25 
and  f3  between  21  and  25 
and  f4  between  21  and  25 
and  f5  between  21  and  25 

/* 
34上→45下→45上→35下→35上→15上→25下→25上→ 
34上→45下→45上→35下→35上→14上→24下→24上→ 
34上→35下→35上→45下→45上→15上→25下→25上→ 
34上→35下→35上→45下→45上→14上→24下→24上→ 
*/

标签:f1,过河,递归,union,来过,SQL,path,where,select
From: https://blog.51cto.com/u_11295556/5953930

相关文章

  • 8:单表查询-MySQL
    (目录)8.1开端细说查询语句8.2select可以查询不存在的表,也可以做计算,别名操作使用as或者省略mysql>select2*7asres;+-----+|res|+-----+|14|+-----+......
  • MyBatis打印SQL语句
     1.Spring+MyBatis这种框架一般还使用的XML配置,所以要在MyBatis的配置文件中加以下信息,就可以打印日志了。<configuration><settings><!--打......
  • MySQL函数
    MySQL函数1.常用函数--======常用函数======--数学运算SELECTABS(-8)--绝对值SELECTCEILING(9.4)--向上取整SELECTFLOOR(9.4)--向上取整SELECTRAND(......
  • MySQL日期 专题
    一、MySQL获得当前日期时间函数 1.1获得当前日期+时间(date+time)函数:now() mysql>selectnow();+---------------------+|now()          |+--------......
  • MySQL8 删除binlog.0000XXX文件导致无法启动
    MySQL8无法启动,由于误删除的日志文件binlog.0000XXX。找到MySQL8目录下的data.err文件中显示的错误信息为:2022-12-19T11:22:23.973011Z0[System][MY-010116][Server......
  • [机器学习] 特征选择笔记3-递归式特征消除
    date:2020-07-0922:11:59+0800tags:-机器学习-Python特征选择代码下载本文主要介绍sklearn中进行特征选择的方法。sklearn.featu......
  • RPC、SQL、NFS属于OSI的哪一层
     第一层:物理层第二层:数据链路层802.2、802.3ATM、HDLC、FRAMERELAY第三层:网络层IP、IPX、ARP、APPLETALK、ICMP第四层:传输层TCP、UDP、SPX第五层:会话层RPC、SQL、N......
  • mysql及redis环境部署时遇到的问题解决
    redis开启远程访问redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf打开redis.conf文件在NETWORK部分有说明解决办法:注释掉bind127.0.0.1可以使所有的ip访......
  • percona-xtrabackup物理备份mysql
    wgethttps://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.4-1.el7.x86_64.rpm安装xtrabackup[......
  • 初探oceanbase和newsql数据库
    为什么是分布式数据库?互联网时代,数据已经成为企业运营的命脉。作为聚合支付的领军企业之一,李俶2021年受理交易金额3500亿,覆盖全国600+城市,服务110万+线下商户,日交易量2300......