QQ登录

只需要一步,快速开始

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

残缺棋盘

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2004-10-4 05:16 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<b>残缺棋盘</b>
& ~: F, N2 M6 v) _  e( a<>残缺棋盘(defective chessboard)是一个有2k×2k 个方格的棋盘,其中恰有一个方格残缺。图2 - 3给出k≤2时各种可能的残缺棋盘,其中残缺的方格用阴影表示。注意当k= 0时,仅存在一种可能的残缺棋盘(如图1 4 - 3 a所示)。事实上,对于任意k,恰好存在22k 种不同的残缺棋盘。
! ^& P+ y" T& x( v  Z+ _" B% w8 _' I  ]2 A$ p
残缺棋盘的问题要求用三格板(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中的某一方向的三格板来覆盖。" O; J" j9 w7 e. K6 q- i* q+ W7 g
- T% N; m8 H, W" f7 q- J4 j' Y: O
用分而治之方法可以很好地解决残缺棋盘问题。这一方法可将覆盖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的棋盘中仅仅包含一个方格且此方格残缺,所以无需放置三格板。- v- N1 u- t( }, ~  s. L3 _
# U0 I6 l; t- U& u; j# H
可以将上述分而治之算法编写成一个递归的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。函数的输入参数如下:: A$ R+ [& R, g' n) g7 M

! G& m( s6 u: ]& U% ^! @4 Y  I! o? tr 棋盘中左上角方格所在行。
4 O( }/ p! e) `' y% v$ z: y
' S, I; x7 f' a1 [? tc 棋盘中左上角方格所在列。$ Y" y# H( u0 ?# [: J8 w

7 V2 E7 s. ~1 J! X4 @2 T( j? dr 残缺方块所在行。1 p% I# t2 D- \# n9 K

8 V9 i4 \5 ]" }( P' `* H? dl 残缺方块所在列。
2 |; |. i) I( s9 M6 C$ y- Y: ]3 A2 S9 W# P) e  G2 _
? size 棋盘的行数或列数。( r8 N7 x/ w) E1 {. T( [

- j* E0 c# v: \- C3 {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来表示这些三格板,并用三格板的标号来标记被该三格板覆盖的非残缺方格。
0 g! A0 e+ {4 V% D/ p- R( S( R2 Y8 p. Z8 w7 K
令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 表示这些额外时间。可以得到以下递归表达式:" I( a2 _( _# Q, _' t3 k

. ~) i* i6 h2 k, j7 I程序14-2 覆盖残缺棋盘* Z# H: t8 Z. ^& J. V9 u8 f

% [/ S, P+ O% tvoid TileBoard(int tr, int tc, int dr, int dc, int size)1 j- p0 h4 |! l

1 ?. @) a1 ~- u2 p6 r4 f) i{// 覆盖残缺棋盘
" r3 A  s. J) f: H5 R- b7 S: q  u# r" u
if (size == 1) return;
# V3 b2 [2 |! \7 b: s
9 C; f& s/ K2 _* Jint t = tile++, // 所使用的三格板的数目8 _8 M1 ?4 J8 G3 g* p5 S

2 U; y, i: d) K% e  Q1 Qs = size/2; // 象限大小& {) h& @: n9 h* M, ~4 b
) P2 T- ~$ x- |; ]# n1 s2 n% F1 H
/ /覆盖左上象限
* N, q7 l. F, @7 u3 e
9 n$ E$ j* w5 Dif (dr &lt; tr + s &amp;&amp; dc &lt; tc + s)1 G* ^( H- S. b/ p" C4 R

  J* ?) g- U$ O// 残缺方格位于本象限7 G2 x; }# P% z% ?! I7 W: X
# T+ j4 e- F+ H( i, r) o% \* ^$ A
Ti l e B o a r d ( t r, tc, dr, dc, s);
; R8 p. @6 P8 |0 o1 O' i" y' ~  H1 v4 X
else {// 本象限中没有残缺方格
: |" c- B$ o0 W
( e  p% P0 i* n0 Q. w" U// 把三格板t 放在右下角9 i( d( Q6 O0 V2 A2 ~
/ O( v3 ?' D  r" V2 C) t/ Z2 P- T+ M4 p
Board[tr + s - 1][tc + s - 1] = t;
- H3 C# `7 [- s
7 N9 v$ J2 A' y& V4 i/ t2 r// 覆盖其余部分
9 O( x8 m7 d! O7 K6 g6 b
0 g6 j1 z& r+ `' o- xTi l e B o a r d ( t r, tc, tr+s-1, tc+s-1, s);}
4 Y/ B( j% V5 c9 F, l  E+ D& R. Y
! A- X4 w: {: Y8 @! d! D/ /覆盖右上象限
2 t: K1 `: C1 W2 q
8 z1 d9 L6 Z+ m1 Uif (dr &lt; tr + s &amp;&amp; dc &gt;= tc + s)% u! O* B$ i) x) S6 J: {6 e
1 L* l( V# }9 J
// 残缺方格位于本象限
/ z$ l- f* H0 \; f6 z" o8 Z5 |8 ~5 Q# N6 y  `( B( c. w& g) @0 j
Ti l e B o a r d ( t r, tc+s, dr, dc, s);
$ ]) L  K$ n$ [. X/ @8 F
" K2 A- E7 p. s; celse {// 本象限中没有残缺方格# G/ `# Q  V' ~# v7 T4 _, Q9 r' q2 b

/ d2 r& k' Z% j6 j// 把三格板t 放在左下角" J; O( b) z9 d6 X8 W

1 G4 D: I, I) g% QBoard[tr + s - 1][tc + s] = t;
3 u. w# p+ X( I1 L8 m9 J" Q' H1 c
// 覆盖其余部分: G' R0 X& o4 J2 \2 E7 ~
1 Z$ J6 H4 I) x2 O& H2 h
Ti l e B o a r d ( t r, tc+s, tr+s-1, tc+s, s);}
- w3 F. q% J4 m/ ]) H. q
( [( d! r0 J9 v/ /覆盖左下象限+ k: u$ n3 j! e7 K, w: X

4 y; \% k" s& fif (dr &gt;= tr + s &amp;&amp; dc &lt; tc + s)& U: i4 f1 C# w, v4 v
) g- J: A  c7 m7 l' I5 J4 d3 d, c" G, t
// 残缺方格位于本象限
; X8 w3 V' _. e4 Q% Y" V# c* {
5 K( P" v' W1 CTileBoard(tr+s, tc, dr, dc, s);
9 |& s( B% C, |
+ w4 o5 g# C8 f2 U& H8 K6 Y$ _. Lelse {// 把三格板t 放在右上角
) R( d1 |2 X; D# _7 }' q2 g/ h5 E( E  q5 E& b7 |) P+ F- X4 R  h
Board[tr + s][tc + s - 1] = t;& Q0 ], ^. p3 m% \, n

, J8 i% q  X* B+ F4 X. d# }/ Z" S4 K// 覆盖其余部分
! Z8 D, R  A* v( W5 i- k0 d4 o
2 |- h2 l. ]( g# s& }5 jTileBoard(tr+s, tc, tr+s, tc+s-1, s);}
4 ?, A8 l. m1 J; G
- j2 d9 n6 h- B" p+ k9 \// 覆盖右下象限6 e) b/ h( e! }; F; Y

* a, z+ X4 \9 Mif (dr &gt;= tr + s &amp;&amp; dc &gt;= tc + s), ~. g8 H: ^" t

( K( d! O3 ?. p; n( X: L: e0 K+ j// 残缺方格位于本象限7 k$ G% _( |# O, R
, b9 C. I0 ?+ i* [( z9 c
TileBoard(tr+s, tc+s, dr, dc, s);6 y. Y. O  U, N! M+ i
+ L6 Q  d, b8 n3 c6 c, ~: ^
else {// 把三格板t 放在左上角9 A- w5 W. Q6 Z, v3 s/ m. Y

; B1 E* g+ z7 o7 @$ a+ v, lBoard[tr + s][tc + s] = t;
) S1 q) G$ Y, t  ~. D, q" P: t2 y5 a
// 覆盖其余部分8 @; m* y! j1 W! n, p

. Y4 |# g& R) f8 l" NTileBoard(tr+s, tc+s, tr+s, tc+s, s);}# y* j$ Q; l0 s% G# B

6 k$ P9 h' H  m* p2 ?) c8 a}
* `. m4 d. T2 v- ^: e6 M3 Y& H* {! Z5 `0 w
void OutputBoard(int size)3 s- A; d; |  l$ T0 d

2 O3 J# y1 {, Y& V9 E{" F0 s' T, ]& l" ^* n' _( J
( J0 M3 R3 R) n4 ^
for (int i = 0; i &lt; size; i++) {$ u+ w: a& L+ x, p; V/ F

9 C+ S" ]. V' u6 o# J6 ]7 O6 \for (int j = 0; j &lt; size; j++)2 {& X' @% r6 \: J
5 f& V; \" i: ]3 Y/ s: U% J+ Q) H
cout &lt;&lt; setw (5) &lt;&lt; Board[j];% ~3 r, |$ w" m2 s8 d; {
! I* u  S# t( f8 ?! v
cout &lt;&lt; endl;! X8 J& _# f8 {; t$ ?2 t
7 \# p' m$ H/ N: w: m
}
! G0 j; S# b4 z9 c4 ^6 x8 I7 Y; c8 g1 B' q' t3 k  h
}
0 L  z" ?; I& _2 H6 ]! B2 C' w" A' I7 V4 ?. n
可以用迭代的方法来计算这个表达式(见例2 - 2 0),可得t (k )= ( 4k )= (所需的三格板的数目)。由于必须花费至少( 1 )的时间来放置每一块三格表,因此不可能得到一个比分而治之算法更快的算法。</P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
yammay        

0

主题

0

听众

16

积分

升级  11.58%

该用户从未签到

新人进步奖

回复

使用道具 举报

wendy28        

0

主题

2

听众

24

积分

升级  20%

该用户从未签到

新人进步奖

回复

使用道具 举报

1

主题

2

听众

60

积分

升级  57.89%

该用户从未签到

新人进步奖

回复

使用道具 举报

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

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

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

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

蒙公网安备 15010502000194号

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

GMT+8, 2026-10-25 04:07 , Processed in 1.558522 second(s), 73 queries .

回顶部