本期题目:
问题1(80分):
在一个6*6的棋盘中,放置12个球,每行、每列、每个正负45度的斜线上最多放置2个球,请用一个SQL语句(不可以用PL/SQL或T-SQL匿名块、过程或函数,也不可以用Java等外部语言)求出不“重复”的摆法的个数(剔除上下对称、左右对称、中心对称,沿中心点旋转等各种变形)
如下是4*4矩阵的几种变形
原始排列
ABCD
EFGH
IJKL
MNOP
左右翻转
DCBA
HGFE
LKJI
PONM
上下翻转
MNOP
IJKL
EFGH
ABCD
中心旋转180度
PONM
LKJI
HGFE
DCBA
沿左上右下对角线翻转
AEIM
BFJN
CGKO
DHLP
沿左下右上对角线翻转
PLHD
OKGC
NJFB
MIEA
中心顺时针旋转90度
MIEA
NJFB
OKGC
PLHD
中心逆时针旋转90度
DHLP
CGKO
BFJN
AEIM
————————————————————————————————————————————————————————
问题2(40分):
在一个N*N的棋盘中,每行放置M个球,每列、每个45度的斜线上最多放置M个球,其中5<=N<=6,1<=M<=(N-1),现要求出每个M,N组合中最多摆放球的不同的摆法的个数(包括重复和不重复的,分别输出)。请用最多两条SQL语句得到以下结果:(以M=2, N=5为例)
两条SQL的输出格式:
[Copy to clipboard] [ - ]
CODE:
SQL1:
M N AllCnt
2 5 92 --上期的结果总数是92,您答对了吗?
SQL2:
M N NoReptCnt
2 5 xx
一条SQL的输出格式:
[Copy to clipboard] [ - ]
CODE:
M N AllCnt NoReptCnt
2 5 92 xx
Oracle变量定义如下(以M=2, N=5为例):
var m number;
exec :m:=2;
var n number;
exec :n:=5;
MS SQL Server变量定义如下(以M=2, N=5为例):
declare @n int,@m int;
set @n=5;
set @m=2;
扩展题的执行方式最好如下:
set timing on
exec :m:=2;
exec :n:=5;
@/sql2-leitaisai.sql
————————————————————————————————————————————————
书写格式:仅包含一个查询语句(可以有子查询)和必要的注释(用/* */括起),不得包含创建表、视图、索引和插入、更新、删除等语句。
输出格式:问题1输出一个整数
问题2输出见题目说明
数据库平台:适用Oracle、MS SQL Server,版本(Oracle推荐10gr2(包含)以上版本、MS SQL Sever推荐2008版本)
原文见:http://www.itpub.net/thread-1403356-1-1.html
参赛者答案:http://www.itpub.net/thread-1411980-1-1.html
我提交的答案:
第一题:
第二题:
解题思路:
两道题的思路相同,见里面的注释
1、得到行符合要求的排列组合
2、用笛卡尔连接生成所有的排列组合
3、去除列与斜边不满足要求的记录
4、将结果做不同位置的旋转,得到字符串
5、取出所有旋转字符串并去除重复的,最后得到结果
6、第二题用UNION ALL的方法组合实现行数为5*5和6*6的输入。
评委点评:
通过把代码写两遍的方法来实现扩展性显得有些笨拙。第一题的优化代码在M变大的情况下就成了累赘。采用5×5和6×6叠加的办法实现,可扩展性差,整体效率也很低。
个人分析:
1、在第一期的基础上,改进了得到行符合要求的排列组合,满足每行棋子数变化的需求。
2、仅能满足5*5和6*6的要求,扩展性极差(水平有限,实在想不出好办法,或者是被第一期的思维给绑定了)。
3、整体性能一般,但是要用同样的思路扩展到7*7的,估计SQL会执行不出来(临时表空间不够,时间会超长)。
4、和第一期一样,相对其他人的代码简单,思路简单,直接了当(其他人的代码基本看不懂,太佩服评委了)。
这道题是SQL大赛4期里面最难的,总体感觉很差,但是评委的最后评分很高,不知道原因是什么(可能其他人更差,也有可能评委搞错了),第1名(2-11)的答题不错(用了11gR2 with递归语法的新特性)。