VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 数据库 > SQL教程 >
  • 能答对这三道SQL题,全国不到58人

很久没怀疑过自己的智商了,直到遇见这 3 道题。

你也来试试!

 

这 3 道巨难的题目,来自 itpub 的 SQL 数据库编程大赛。说起 itpub 就不得不说它与 Oracle 的渊源,多少大师都在这里诞生。想成为 SQL 大师,有个最快的方法,就是刷题。如果能刷遍这里的题,Oracle 工作,十拿九稳。当年支付宝首席数据库架构师冯大-冯春培,就是典范。

好了,闲话不说,上题!

 

 

1,5X5方格棋盘难题

在5X5的方格棋盘中(如图),每行、列、斜线(斜线不仅仅包括对角线)最多可以放两个球,如何摆放才能放置最多的球,这样的摆法总共有几种?输出所有的摆法。

 

要求:用一句SQL实现。

 

输出格式:

从方格棋盘第一行至第5行,每行从第一列到第5列依次输出,0表示不放球,1表示放球。

 

例如:

1001000000000000000000000。

 

一行输出一个行号和一个解,按解所在的列字符串顺序从大到小排序。

 

详情:itpub.net/thread-140006答案:itpub.net/thread-140707我想说:尽量自己做,否则即使看了答案,对提高技能也无帮助

 

难理解的是,最长的对角线上也不能有 3 个 1

 

 

2,挖地雷之标出有地雷的格子

在M*N的矩阵中,单元格中的数字表示该单元格周围地雷的数目,有数字的单元格肯定不是地雷。其余的单元格要么是地雷,要么是空位而且四周都没有地雷。

 

周围的定义为紧挨着的单元格,例如:

 

若单元格在矩阵的内部,则周围有8个单元格,如图a所示
若单元格在矩阵的四边,则周围有5个单元格,如图b所示

若单元格在矩阵的四角,则周围有3个单元格,如图c所示

 

 

输入输出格式:



用3个变量v_height、v_width、v_cnt表示雷区的长度、宽度和地雷个数,其中v_height、v_width均为大于0且小于32的整数,v_cnt为大于0且小于或等于v_height*v_width的整数。

 

 

用1个字符串变量表示从矩阵第一行至最后一行,每行从第一列到最后一列依次输出

如矩阵(为明显起见,用下划线表示空格,实际做题的输入输出仍用空格)

的字符串表示为:

 

正题 1):挖地雷之标出有地雷的格子

题目要求:用一句SQL实现

 

有若干地雷分布在图中,它们都有*标记,请把矩阵中的数字标出来。
如输入字符串为:

 

输出格式:在输入字符串中有地雷的位置保留'*',同时对它周围的单元格标上地雷数,若单元格周围没有地雷,则保持空格,对上述输入,则输出:
111 2*1 *32112*1


正题 2):挖地雷之标出有地雷的格子

题目要求:用一句SQL实现或用一个PL/SQL函数实现。

(如果用PL/SQL实现,则函数必须为

create or replace function 
winmine(p_str varchar2,
p_width NUMBER,
p_height NUMBER,
p_cnt NUMBER
)return varchar2
asbegin...
return ...;
end;/​

结果在sqlplus用

selectwinmine(:v_str,:v_width,:v_height,:v_cnt)fromdual;

输出


如果有相应授权需要把grant语句一并给出,用户名为scott)

 

有C个地雷分布在图中,根据输入字符串提供的格子周围地雷数,把所有埋了地雷的格子标出来。

如输入字符串为:

VAR v_str VARCHAR2(1000);
exec :v_str :='111 2 1  32112 1'

输入地雷数为:

var v_cnt NUMBER;
EXEC :v_cnt := 3;

输出格式:在输入字符串中有地雷的位置标上'*',同时保留它周围的单元格标的地雷数,若单元格周围没有地雷,则保持空格,对上述输入,则输出:
111 2*1 *32112*1

本题不需要考虑错误处理,如果输入错误(比如地雷数输入变量和实际不符、雷区不是矩形、字符串中标的地雷数字错误),就允许任何输出。

数据库平台:Oracle 11g R2 版本(不能用12c,因为它有在sql语句中编写自定义函数功能)

详情:itpub.net/thread-182502

 

3,井字棋

两个玩家,一个打圈(O),一个打叉(X),轮流在3乘3的井字格上打自己的符号,最先以任意一行、一列或对角线连成一线则为胜。规定X先手。

 

一个终局棋谱(MOVES)指的是从开始下子到一方获胜或者下完9个子出现平局,从头到尾的下子情况。一方获胜后,本局即终止。不得提前认输。

 

格子从上到下,从左到右,依次编号1-9

 

MOVES的第一位表示第一子位置,第二位表示第二子位置,......如果一方获胜,MOVES的长度有可能<9。

 

局面(BOARD)表示棋盘上呈现的局面,也是按照从上到下,从左到右排列。用X和0填入相应的格子。减号“-” 表示空位。

 

这里有个棋局:

 

表示出来是:

MOVES=3175968,

BOARD=O-X-OOXXX,

WINNER=X

 

第一题:求出所有可能终局棋谱和相应的局面,插入如下的表中:

CREATETABLE TICTACTOE (MOVES VARCHAR2(9) PRIMARY KEY,BOARDVARCHAR2(9),WINNER VARCHAR2(1));

格式要求:

 

首先CREATE 上述TICTACTOE表。然后用一个能直接放在“insert into TICTACTOE ”后面成功运行的SQL查询语句,一次性插入所有满足标准的棋谱和相应的局面、胜者(WINNER=X或O或D,其中D表示平局)

 

 

注意:本题要求生成所有可能的终局棋谱,只要符合规则即可,哪怕其中有些走法可能看起来很愚蠢,也得包含进去。还没下完的棋谱不要列入。

 

如果两个终局的局面(BOARD)相同,但是其下子顺序(MOVES)不同,则视为不同棋谱,两个都必须出现在结果中。

 

如果两个棋谱的MOVES不同,但是其终局局面(BOARD)经过旋转、翻转后重合,仍然被视为不同棋谱,两个都必须出现在结果中。

 

 

 

第二题:给定一个局面,假定该局面一定为有效(不会出现一方比另一方多两子的情况,或者两方都有三子连线的情况),用SQL判断出哪一方有必胜策略,以及获胜方最多再下几子必定会获胜。比如输入:V_BOARD='X-0------' 则输出'X3',表示WINNER=X,下子数=3,因为不管对手怎么走,X最多再下3子一定获胜。(不计入O再下的子数)

 

如果O方有失误,也有可能X再下两子就取胜的;X方也有可能下错而输掉,但这些都不在本题考虑范围,假定双方都是完美棋手,即双方都尽可能取胜,不能取胜则尽可能求和,不能求和则尽可能多下几子。

 

如果给定的局面中一方已经获胜,则输出获胜方符号和子数0,例如输入:V_BOARD='OXX—XOOX', 则输出'X0'

 

如果不存在必胜策略(比如一个空局:V_BOARD='---------'),则输出'D'。

 

输出中都不含单引号。

 

格式要求:

 

首先在sqlplus中声明变量var v_BOARDvarchar2(9),再对变量赋值(如:exec :v_BOARD:='X-O------')。然后用一个包含变量v_BOARD的查询语句,返回对应此棋局的结果字符串(X数字,或O数字,或D表示平局)

 

 

第三题:m,n,k游戏是指两个对手在m*n的棋盘上轮流下子,谁先在纵、横、四十五度斜线上连续取得k个子就获胜的一种游戏,井字棋游戏其实就是3,3,3的一种特例。五子棋则为15,15,5游戏。

 

上述按第二题的要求,使得SQL能够适用于m,n,k大于等于3的情况 。

 

详情:itpub.net/thread-194391

相关教程