QQ登录

只需要一步,快速开始

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

残缺棋盘

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2004-10-4 05:16 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<b>残缺棋盘</b>- P# q# H& ^3 ^/ s5 }& I3 x" y
<>残缺棋盘(defective chessboard)是一个有2k×2k 个方格的棋盘,其中恰有一个方格残缺。图2 - 3给出k≤2时各种可能的残缺棋盘,其中残缺的方格用阴影表示。注意当k= 0时,仅存在一种可能的残缺棋盘(如图1 4 - 3 a所示)。事实上,对于任意k,恰好存在22k 种不同的残缺棋盘。8 B) }) p5 t, Z( H/ q6 y' X0 o( v
) r0 x; S) X9 K, y6 U5 [3 D6 C
残缺棋盘的问题要求用三格板(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中的某一方向的三格板来覆盖。
& ]9 y/ @4 }7 y
% p" X  J( z, n2 M8 Z( B- e. [用分而治之方法可以很好地解决残缺棋盘问题。这一方法可将覆盖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的棋盘中仅仅包含一个方格且此方格残缺,所以无需放置三格板。
. P' a3 L$ l" N- p" v& o) X% P, T# \' {# g) \3 C7 d
可以将上述分而治之算法编写成一个递归的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。函数的输入参数如下:4 ^; S7 X# ^* h; p) \1 e3 E3 K

5 k- `0 P$ P. @% N? tr 棋盘中左上角方格所在行。
/ c! v7 Z0 X4 P4 z% K& v
% p8 C; ?4 j6 K) Y6 R' O4 u/ S, `? tc 棋盘中左上角方格所在列。3 G6 s# z( Z3 c9 ^$ f

: h9 v, m5 x5 n, s3 N4 R? dr 残缺方块所在行。4 ~  T, ]6 j9 Q( ~
' G1 B8 k! R  L+ H5 F
? dl 残缺方块所在列。) `' U. V9 y7 b

6 g+ s, W5 ?. n- b? size 棋盘的行数或列数。! e5 W  J0 m/ z

8 O7 X* X  c( L6 k8 {! WTi 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来表示这些三格板,并用三格板的标号来标记被该三格板覆盖的非残缺方格。
: X; @2 Z% U  X; n* [# d6 G" y7 s
令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 表示这些额外时间。可以得到以下递归表达式:9 @, V" N# F$ I" y
9 g1 i5 X0 g! s" Y6 G3 R* ?
程序14-2 覆盖残缺棋盘# T4 A! ^  c) s4 _  X! a

; q; A. |* L% A# @void TileBoard(int tr, int tc, int dr, int dc, int size)- I* k+ f9 }: p5 z+ [
. @* \  H& F7 ~5 i6 r4 k
{// 覆盖残缺棋盘
3 ?0 O; @: u9 Y0 P. p0 D- Z
9 S1 W- b8 p6 k% oif (size == 1) return;, g" B  y4 E! f, X* x

( S- p* J: ?# e6 y* c: Jint t = tile++, // 所使用的三格板的数目7 m. _2 `- ~8 q0 C0 _1 {( o
8 I4 z6 N" F# c3 k& C! ]- u* O
s = size/2; // 象限大小
3 S% i5 A7 d3 C: x1 q2 |$ k0 t' r7 ]% `
/ /覆盖左上象限0 b1 j5 V. a" ^/ h+ |6 X

* j: C& i. H- X* q9 zif (dr &lt; tr + s &amp;&amp; dc &lt; tc + s)
- e6 J4 p5 H' T- B2 T1 F2 W. o9 V9 \! {
// 残缺方格位于本象限$ W' u+ ?+ [2 {7 C9 U- ^; c" B# U
9 l  @8 J; _, y' Z' U
Ti l e B o a r d ( t r, tc, dr, dc, s);( E9 A  q- Q3 g3 U- D$ I" o  Y, b5 x
% |/ U& m: ^- O& o* F
else {// 本象限中没有残缺方格2 C) R! `- M% g; Z8 q5 a2 k" y  O3 s9 s0 O
& ~4 C9 c- B( Y6 g2 A5 ]7 P0 G
// 把三格板t 放在右下角
# x( @: f7 W" e+ @- l7 j# y- h" v+ }- z$ X& f/ N1 f- B
Board[tr + s - 1][tc + s - 1] = t;  F0 ~0 f9 E5 W2 B
/ c. ~' s- Y: z& V0 R" s; |
// 覆盖其余部分  C( J8 M4 M" Z5 }
* \! I. M. J/ a: y
Ti l e B o a r d ( t r, tc, tr+s-1, tc+s-1, s);}
. s) ^; b& N: Z# t& A) ^
1 V3 u9 q* I0 D, k3 i# L/ /覆盖右上象限
# A+ S  Z: d! ~2 J3 P) P9 G5 s
7 y' R& D8 @+ a% L) aif (dr &lt; tr + s &amp;&amp; dc &gt;= tc + s)
; B( c- e6 B5 e: F9 r& j, Z: j0 T' X9 z# f% d# E3 Y3 {% w3 ^8 l3 f, t
// 残缺方格位于本象限
$ x- i! _& F5 I+ C7 K( G3 i2 Y2 p% ]7 d5 I3 i7 J: u3 ]
Ti l e B o a r d ( t r, tc+s, dr, dc, s);  X& O2 l+ G! ?- I3 Q

  l% A. x6 c% relse {// 本象限中没有残缺方格8 G# {! i6 N. e- ~8 A2 t: k
$ h" c. j8 q+ [) V0 f. d
// 把三格板t 放在左下角
. \  @) K6 u7 V% f; c& |
" p9 e" |8 i6 bBoard[tr + s - 1][tc + s] = t;
  J2 h' d) ^2 Z% y! e& {+ D0 D6 @$ c, X8 y" @. b
// 覆盖其余部分, N3 ^3 ~' f3 O
" l/ u$ q( d  x9 m! @/ v
Ti l e B o a r d ( t r, tc+s, tr+s-1, tc+s, s);}5 @5 c# F; s* S. p
3 O3 l/ x! p, z+ q0 T9 L( q
/ /覆盖左下象限% v- h. t7 w4 m/ [& h
) i8 @8 ~5 B7 e4 R0 p* F
if (dr &gt;= tr + s &amp;&amp; dc &lt; tc + s)( U1 f" w! y' a% {0 J" W4 j8 n+ r
% ^$ L1 f5 p' q: P" x2 P# [3 f
// 残缺方格位于本象限  a: ?+ c# }( |/ r

( t+ x# K7 n& l3 YTileBoard(tr+s, tc, dr, dc, s);
) Y; {; J$ [6 h+ u! V% [. |
, V* H- N/ B. v+ m3 U: b, {4 B: V; Qelse {// 把三格板t 放在右上角1 B7 B) }! F" G
+ Z3 V* F- k8 j% x  c& [& F. Y
Board[tr + s][tc + s - 1] = t;
2 S; d; {- j5 g5 p- B
  u- [5 {8 J3 e* @; N# e// 覆盖其余部分
5 m8 {/ W" n1 [( c- @7 S, I+ G& c3 X; ~
TileBoard(tr+s, tc, tr+s, tc+s-1, s);}$ B+ ~1 z! N! B( H. p1 Q1 ]

8 Y/ U3 [( C/ Z5 I/ j// 覆盖右下象限
7 O3 ^; z& t! o* ]4 `
3 I0 h/ C/ v. V5 @# ^) s6 t7 }if (dr &gt;= tr + s &amp;&amp; dc &gt;= tc + s)
1 ~1 v0 z6 m4 \- E" O/ O; k: M  V/ V$ I6 m4 E
// 残缺方格位于本象限  H0 F* P2 u, Y* W$ s2 i

4 B' G& S! S' T" Q9 ?+ T  c+ t6 gTileBoard(tr+s, tc+s, dr, dc, s);
- Z2 Y7 h: V  g6 `8 }% b- b- Y- Z/ A) A
else {// 把三格板t 放在左上角& Z* c' |- |. G2 d6 ^

! T7 I0 ^2 P0 x* p1 lBoard[tr + s][tc + s] = t;1 I+ G' f& u2 W% l

, y! y  q+ _8 R// 覆盖其余部分2 P7 b& P% f; K% V" u( l

) x7 ?! w9 ]$ H* e, MTileBoard(tr+s, tc+s, tr+s, tc+s, s);}
  L: A. M5 q3 B( a7 D* J" J5 E, Q+ U$ ]6 j, A2 V1 M
}
' n! T* P1 ?( h& W7 w* J; {6 {) ?2 i* K+ f
void OutputBoard(int size)
0 m4 |9 c8 b4 P  ], n
( i; ~# O) S+ ^$ |{
/ W9 {5 G* G9 }6 ~% V, E, [1 h
for (int i = 0; i &lt; size; i++) {/ J0 G  R6 d6 r) @  U) Z8 S7 n
9 Z4 e: D4 H' j# h: ?
for (int j = 0; j &lt; size; j++)
* ^& U. \9 [2 K1 P$ T
' Z6 ]8 v3 t$ P% \1 Qcout &lt;&lt; setw (5) &lt;&lt; Board[j];; J6 y, A' G) n/ m4 Y7 r
: n( z7 E% s6 X* o
cout &lt;&lt; endl;
  e. n9 f2 ?; ]2 |, y" D3 y1 x6 R8 h" r( p, [, `0 B1 ?; o
}" P2 O- \8 r4 w# B

% x6 b) N! D8 j# d- E+ Q% _/ G}* o+ Q0 l- ~$ O# a

1 V8 @' ?) b; j! x& {, Y' L可以用迭代的方法来计算这个表达式(见例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-6-15 12:02 , Processed in 0.527056 second(s), 76 queries .

回顶部