QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3886|回复: 3
打印 上一主题 下一主题

残缺棋盘

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2004-10-4 05:16 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<b>残缺棋盘</b>
6 V  n" I9 ~  u7 p" `6 L% q<>残缺棋盘(defective chessboard)是一个有2k×2k 个方格的棋盘,其中恰有一个方格残缺。图2 - 3给出k≤2时各种可能的残缺棋盘,其中残缺的方格用阴影表示。注意当k= 0时,仅存在一种可能的残缺棋盘(如图1 4 - 3 a所示)。事实上,对于任意k,恰好存在22k 种不同的残缺棋盘。
4 t) w- [" B6 Y6 S
# d2 q% W" k$ u& t+ e残缺棋盘的问题要求用三格板(t r i o m i n o e s)覆盖残缺棋盘(如图1 4 - 4所示)。在此覆盖中,两个三格板不能重叠,三格板不能覆盖残缺方格,但必须覆盖其他所有的方格。在这种限制条件下,所需要的三格板总数为( 22k -1 ) / 3。可以验证( 22k -1 ) / 3是一个整数。k 为0的残缺棋盘很容易被覆盖,因为它没有非残缺的方格,用于覆盖的三格板的数目为0。当k= 1时,正好存在3个非残缺的方格,并且这三个方格可用图1 4 - 4中的某一方向的三格板来覆盖。
5 U0 I6 w7 p2 P1 C+ [
( f2 z0 G, n- L" i+ y" x用分而治之方法可以很好地解决残缺棋盘问题。这一方法可将覆盖2k×2k 残缺棋盘的问题转化为覆盖较小残缺棋盘的问题。2k×2k 棋盘一个很自然的划分方法就是将它划分为如图1 4 - 5 a所示的4个2k - 1×2k - 1 棋盘。注意到当完成这种划分后, 4个小棋盘中仅仅有一个棋盘存在残缺方格(因为原来的2k×2k 棋盘仅仅有一个残缺方格)。首先覆盖其中包含残缺方格的2k - 1×2k - 1 残缺棋盘,然后把剩下的3个小棋盘转变为残缺棋盘,为此将一个三格板放在由这3个小棋盘形成的角上,如图14-5b 所示,其中原2k×2k 棋盘中的残缺方格落入左上角的2k - 1×2k - 1 棋盘。可以采用这种分割技术递归地覆盖2k×2k 残缺棋盘。当棋盘的大小减为1×1时,递归过程终止。此时1×1的棋盘中仅仅包含一个方格且此方格残缺,所以无需放置三格板。
  Z9 E9 D! e: M% D5 a2 ]# w1 R) {( _
可以将上述分而治之算法编写成一个递归的C++ 函数Ti l e B o a r d (见程序1 4 - 2 )。该函数定义了一个全局的二维整数数组变量B o a r d来表示棋盘。B o a r d [ 0 ] [ 0 ]表示棋盘中左上角的方格。该函数还定义了一个全局整数变量t i l e,其初始值为0。函数的输入参数如下:% p+ f, Y  c+ v  W2 J' s

4 b: J: M' ]; [? tr 棋盘中左上角方格所在行。
; m* p4 h) P6 U* A- M+ L$ p6 ?) f" ~5 j7 I( a" Q, U; u
? tc 棋盘中左上角方格所在列。
7 e1 B* b! E7 O0 ?/ X* K# e. t" h' n
? dr 残缺方块所在行。
1 m% a  |8 B- M! A
' C- c. ~  B+ t! o. f? dl 残缺方块所在列。5 r' D1 s3 R" S& Y' s

+ O" r4 i* o  c) H7 i* l, s? size 棋盘的行数或列数。
# I. e) n( s5 L4 x- t) f* y' D8 I) H, B* a
Ti l e B o a r d函数的调用格式为Ti l e B o a r d(0,0, dr, dc,size),其中s i z e = 2k。覆盖残缺棋盘所需要的三格板数目为( s i z e2 -1 ) / 3。函数TileBoard 用整数1到( s i z e2-1 ) / 3来表示这些三格板,并用三格板的标号来标记被该三格板覆盖的非残缺方格。
2 v# \9 L/ Q$ i& g- W& @" @' T/ r5 F% I7 [' c
令t (k) 为函数Ti l e B o a r d覆盖一个2k×2k 残缺棋盘所需要的时间。当k= 0时,s i z e等于1,覆盖它将花费常数时间d。当k &gt; 0时,将进行4次递归的函数调用,这些调用需花费的时间为4t (k-1 )。除了这些时间外, if 条件测试和覆盖3个非残缺方格也需要时间,假设用常数c 表示这些额外时间。可以得到以下递归表达式:( ?# G  I6 z5 l: t* W. W

8 l, G9 T% e! ~程序14-2 覆盖残缺棋盘( q  n' c9 I& K5 A5 |. Y
9 h4 D1 [3 g2 m5 n$ P% z
void TileBoard(int tr, int tc, int dr, int dc, int size)
$ o% f$ Q2 D: r9 {2 _- ]
" x/ R- m3 c1 k8 i/ p: l/ \$ e3 Q4 y8 x{// 覆盖残缺棋盘
+ W  Q( M  E' K+ n+ o9 j9 O6 K5 Q! S; x7 E  T5 `* G
if (size == 1) return;
# j- c6 G: E0 `# ^$ d% }0 g- U: L# }! R& ?8 t
int t = tile++, // 所使用的三格板的数目
9 F( U8 ^& [( F* D
' F* T3 S& H/ I! Vs = size/2; // 象限大小0 ?6 F. d- Y8 K( [) n) ^2 K  J

, f* y6 Z( G5 m5 p/ /覆盖左上象限. n$ F7 S) p7 f! \# O( E# Q

# u' P* p( y: P5 L: X8 d4 \if (dr &lt; tr + s &amp;&amp; dc &lt; tc + s)
. r5 S0 |* }- }, r, ^% P$ y3 Y# M  n$ L! D  q) B7 }$ l5 N* x/ I
// 残缺方格位于本象限
. E. s' ?* T9 O& S  v! h; R9 J6 y* |; w" E0 c5 t& d
Ti l e B o a r d ( t r, tc, dr, dc, s);( _, q! [& b* {
( G& E$ p. O! ]. `
else {// 本象限中没有残缺方格# m: l! s) o3 G5 n+ c# S
* @/ m/ F( A7 X7 A9 A$ f, s) E4 S
// 把三格板t 放在右下角/ a# |5 {7 }6 d5 b+ R

; }8 t: Y( i) B( s( k: s8 e" lBoard[tr + s - 1][tc + s - 1] = t;! }; l" T* \0 g4 y( i5 n, P

. N5 ^  y$ K) [$ P" P// 覆盖其余部分
* d9 T* w1 B& a8 x* h) m9 k' n4 H4 u. J8 y+ j# U; L) N' d# G; {" G) W
Ti l e B o a r d ( t r, tc, tr+s-1, tc+s-1, s);}# e! Y+ x4 _8 s- U. N" E
0 M+ Y* }+ z$ j3 V; q# c* |
/ /覆盖右上象限) B  N. Q5 r% Q% ?5 H
. v" E, _& {$ a! ]1 x  l/ {6 c
if (dr &lt; tr + s &amp;&amp; dc &gt;= tc + s)& R, P  K5 B% U, a0 ^, b1 w. U$ C# ?

: Z8 ?/ M% K1 l// 残缺方格位于本象限" O6 N& Z. C3 d# b0 u

6 F7 C) w- b' q/ b9 b% n' h5 ?Ti l e B o a r d ( t r, tc+s, dr, dc, s);' y2 o3 c; w& k! s4 ^: g' k7 F  b$ u
1 c0 w6 G) p, @" _" i- {" X
else {// 本象限中没有残缺方格
: |" g: k# x& Z/ C1 i% u' Y- ?* @, i
& Q! A; c" G8 t5 d6 U9 _; ]// 把三格板t 放在左下角
3 L: b  h% T$ H' d4 A* e. w! f5 m) x# D' o) k4 X+ a
Board[tr + s - 1][tc + s] = t;
; R. \" P( j0 B& O  _" D) ?) X2 S  w7 i2 o) W: `2 G
// 覆盖其余部分9 {6 @6 i0 A0 L. m2 R; u) Y+ D2 Z
& D$ J7 r, J: }) A0 {
Ti l e B o a r d ( t r, tc+s, tr+s-1, tc+s, s);}
) z/ e! b- X+ c8 H4 t& Q
0 u4 A) p9 |- W" W/ /覆盖左下象限# T% `8 h, ^# m& |+ c1 ?2 p
5 z" F- s1 y0 V( n' o
if (dr &gt;= tr + s &amp;&amp; dc &lt; tc + s). b" U8 e3 z* K: a1 p
  m/ _: T: C) _. v+ z$ f% \: c
// 残缺方格位于本象限" O0 e* y  o  u) B% G

2 x5 O* T/ p8 A4 nTileBoard(tr+s, tc, dr, dc, s);' {$ \, Y2 M) z1 ?3 E" J

; ~5 K3 R$ X! Y* Kelse {// 把三格板t 放在右上角# g! |- _  x# I$ ?4 ?
% K3 a6 `, Q! l2 x
Board[tr + s][tc + s - 1] = t;% f+ A2 L4 \' P: z

6 Z% F2 w1 y+ T! W( _9 v6 w// 覆盖其余部分
( H, P# p3 b6 d# u. r1 o0 ?
* ?: {! ^! P: u- r% Z! O1 k4 \  ]" s* XTileBoard(tr+s, tc, tr+s, tc+s-1, s);}
1 V- ?  u0 q' o- e& ]1 A9 g9 Y
  k& }2 U1 T/ ]6 E9 J$ G// 覆盖右下象限$ G  t2 `6 z; @) J& t

& t/ {- ]5 i4 |$ {3 `+ `if (dr &gt;= tr + s &amp;&amp; dc &gt;= tc + s)
3 H; l! C, S7 a9 h! A5 s9 U0 F* R% w  C! j
// 残缺方格位于本象限6 y( U+ F" m: n1 l4 J* d

; V# _  r! g, u* t( N0 kTileBoard(tr+s, tc+s, dr, dc, s);
9 d4 H% @# B* R# U2 S- s; A4 o; T# `7 W6 c
else {// 把三格板t 放在左上角/ D9 a, f8 _4 e4 M! h

% }4 Z4 ^6 D# \Board[tr + s][tc + s] = t;1 h* E; t1 ]3 Z* ?- l  X7 h4 m
8 |! d+ r9 X- [$ Y1 R/ [
// 覆盖其余部分
* {" U) l4 I+ M8 |8 c% {, `0 x' G
/ W- Y; h) p* q- a- |& M; \2 sTileBoard(tr+s, tc+s, tr+s, tc+s, s);}
* |  i* Z% A) [- Z* \. x0 G: b6 e. Y5 Y. i
}
4 u% ?# W% r  l! K9 c9 v) T: I/ G6 _
void OutputBoard(int size)% c2 j3 a0 Z0 L
' d' y' D/ j  A* o( B/ M: ^
{6 @3 [8 m3 h* s7 p

) m+ W$ z3 `7 ~! O+ Z. U* gfor (int i = 0; i &lt; size; i++) {
& e( m/ @/ Q; {/ T2 q' J! C! `" {0 c& q  O: n6 p; m( G0 ^' f
for (int j = 0; j &lt; size; j++). i. q/ q  \4 }5 j% b
* [7 A: n  a9 ^$ f3 |# @# M: D
cout &lt;&lt; setw (5) &lt;&lt; Board[j];
, ?/ N8 O7 a0 a2 Y
# `" M- u  e% C1 Z! f( O; t1 Wcout &lt;&lt; endl;
' p5 {# l+ {0 |2 q% H8 ?6 ?* k. O2 u- S3 |$ {
}
2 ]( J* ^7 M3 G! y7 G7 K
; g& E) N* H# C) g, J  t}
' p6 q) O9 r) S6 V# k  R2 r8 N$ ~
  }# b! q9 [# @$ X: d( ^$ h6 L8 v可以用迭代的方法来计算这个表达式(见例2 - 2 0),可得t (k )= ( 4k )= (所需的三格板的数目)。由于必须花费至少( 1 )的时间来放置每一块三格表,因此不可能得到一个比分而治之算法更快的算法。</P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信

1

主题

2

听众

60

积分

升级  57.89%

该用户从未签到

新人进步奖

回复

使用道具 举报

wendy28        

0

主题

2

听众

24

积分

升级  20%

该用户从未签到

新人进步奖

回复

使用道具 举报

yammay        

0

主题

0

听众

16

积分

升级  11.58%

该用户从未签到

新人进步奖

回复

使用道具 举报

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

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-10-23 09:45 , Processed in 1.714276 second(s), 76 queries .

回顶部