You are on page 1of 740

,

,
( 2).
,

():
: http://www.programirane.org
Facebook : http://www.facebook.com/groups/168112146541301

10 2013

1 - ,

2 740

: , 2012.
, , .
.

.
= ++;
pdf , , ,
.

, .
,
pdf .


............................................................................................................................. 3
.......................................................................... 13
........................................................................... 15
0 , , 17
0.1. .................................... 18
0.1.1. - ................................................................................... 18
0.1.2. .................................................................... 19
0.1.3. ................................................................... 20
0.1.4. ............................................................................... 20
0.1.5. ...................................................................................................... 21
0.1.6. ...................................................................... 21
0.1.7. ........................................................... 22
0.2. ................................................................................................................ 23
0.3. ................................................................................................... 24
0.3.1. ............................................................................. 24
0.3.2. ......................................................................................... 25
0.3.3. ................................................................................................. 25
0.3.4. .................................................................................................................... 26
0.4. = ++........................................................................................... 26
0.4.1. ................................................................................ 26
0.4.2. ................................................................... 27
0.4.3. C? .......................................................................................................................... 28
0.4.4. ............................................................................. 29
0.5. ........................................................................................................................... 29
................................................................................................................................. 29
0.5.1. ................................................................................................................ 29
0.5.2. ........................................................................................................... 30
0.5.3. .................................................................................................... 30
1 ...................................................................... 33
1.1. ........................................................... 33
1.1.1. .............................................................................. 33
- ...........................................................................................................................33
- ....................................................................................................................................35
- . ...................................37
- ...........................................................................................................38
- , , n- ............................................................................................39
- . ........................................................................................40
- ...............................................................................................................................41

1.1.2. ........................................................... 43
1.1.3. ................................................................................................................... 44
- ................................................................................45
- . ...............................................47
- ..............................................................................50
- , ........................................51

1.1.4. ...................................................................................... 52
- .................................................................................................................52
- . .....................................................................................54

1.1.5. , . ........................... 56
1.1.6. ................................................................................ 59
- p- .........................................................61
- p- . .......................63

1.1.7. .................................................................................................................. 65
- .............................................................65
- ....................................................................66

1.2. ............................................................................................................ 67
1.2.1. ....................................................................................................................... 68
1.2.2. ...................................................................................................... 69
1.2.3. - . ........................................................ 74
1.2.4. - ............................................................................................... 76
1.2.5. ....................................... 77
1.3. ................................................................................ 80
1.3.1. ..................................................................................................................... 80
- ...........................................................................................................................81
- .......................................................................................................84
- ...................................................................................................86

1.3.2. .......................................................................................................................... 86
- , .............................................................................................................86
- .............................................................................................................................88

1.3.3. ..................................................................................................................... 90
1.3.4. ......................................................................................................... 92
- ...........................92
- .........................93
- ...........................94

1.3.5. ............................................................................................. 96
- .....................................................................................................96

1.4. ................................................................................... 97
1.4.1. ............................................................................................ 99
1.4.2. ............................................................................................... 99
1.4.3. O(F): ..........................................................................................100
1.4.4. (F): .........................................................................................102
1.4.5. (F): .........................................................................................103
1.4.6. ..................................................................105
1.4.7. ..........................................................................106
1.4.8. ..................................................................107
- ....................................................................................................... 107
- ....................................................................................... 107
- ................................................................................................ 107
- if- ................................................................................................................... 107
- ................................................................................................................................. 108
- .................................................................................................................. 108
- ....................................................................................... 109
- ................................................................................................... 110
- ............................................................................................................................ 110

1.4.9. .....................................................................................112
- ............................................................. 112

- .............................................................. 114
- ..................................................................................... 114

1.4.10. ........................................................117
- .................................................................................................. 117
- .................................................................................................... 118
- ............................................................................................................... 118

1.4.11. ..............................................................120
1.5. ...............................................................................................................120
1.5.1. ........................................................................................................120
1.5.2. ..................................................................................................................133
- , , .................................................................................... 133
- .................................................................................... 137
- ....................................................................................................... 138

2 ...............................................143
2.1. , , ........................................................................................................144
- .................................................................................................................................... 145
- ............................................................................................................................... 146
- ..................................................................................................................................... 147

2.1.1 () ..................................................................147
- .................................................................................................................................... 147
- ............................................................................................................................... 149

2.1.2 () .............................................................................151
- ....................................................................................................... 152
- ........................................................................................................ 153
- , ........................................................... 153
- , ........................................................... 154
- ....................................... 154
- , ................................................................ 155

2.2. ................................................................................................................158
- ..................................................................................................... 163
- ..................................................................................................... 164
- .................................................................................. 164
- ......................................................................................................................... 168

2.3. ........................................................................................................169
2.3.1. . - .............................................................................172
2.3.2. B- ......................................................................................................................174
2.4. - ........................................................................................................................176
- - ..................................................................................................................... 176
- ............................................................................................................................. 177

2.4.1. - .............................................................................................178
- ................................................................... 178
- .............................................................................................. 178
- - ................................................................................. 179
- - .......................................................... 179
- - .............................................................................. 180

2.4.2. .......................................................................................................184
- ............................................................................................................184
- ............................................................................................................. 184
- ...................................................................................................... 185
- .............................................................................................................. 185

- ..............................................................................................................185

- ........................................................................................ 185
- .................................................................................................. 186

2.4.3. - .......................................................................................186
2.5. ...............................................................................................................192
2.5.1. ........................................................................................................192
2.5.2. ..................................................................................................................196
3 ...........................................................................................................199
3.1. ................................................................................................200
3.1.1. .................................................................................................200
3.1.2. ...........................................................................................201
3.1.3. . .............203
3.1.4. ....................................................................................................206
3.1.5. .............................................................................................207
3.1.6. ...........................................................................................208
3.1.7. .....................................................................213
3.1.8. ........................................................................................215
3.1.9. .........................................................................216
3.1.10. .....................219
3.2. ......................................................................................221
3.2.1. ......................................................................................221
3.2.2. ................................................................................................223
3.2.3. ..................................................................................................226
3.2.4. .....................................................................................229
3.2.5. ......................................................................................232
3.3. ........................................................................................................233
3.3.1. ...............................................................................235
3.3.2. .................................................................................236
3.3.3. ...............................................................................................237
3.3.4. ........................................................237
3.3.5. ..............................................................................................................237
3.3.6. .........................................................................................................238
3.3.7. .........................................................................238
3.3.8. - ...............................................................239
3.3.9. - .............................................................................239
3.3.10. ...............................................................................................239
3.4. ...............................................................................................................240
3.4.1. ........................................................................................................240
3.4.2. ..................................................................................................................243
4 .................................................................................................................245
4.1. .................................................................................................246
4.1.1. .........................................................248
4.1.2. ...........................................................249
4.2. . ..................................................................251
4.3. .................................................................................................................252
4.4. .......................................................................................................256
4.5. ..............................................................................................258
4.6. ...............................................................................................................260
4.6.1. ........................................................................................................260

4.6.2. ..................................................................................................................261
5 .......................................................................................263
5.1. ...............................................................................................................263
5.2. ........................................................................267
5.2.1. .......................................................................................................267
5.2.2. , .......................................................268
5.2.3. ( ) .............................................268
5.2.4. ............................................269
5.2.5. ........................................................................................269
5.2.6. ...............................................................270
5.3. ............................................................................................................271
5.3.1. ...................................................................................................271
5.3.2. ..............................................................................................274
5.4. , ................................................................276
5.4.1. .......................................277
- - ................................................... 277
- ......................................................................................... 279
- ...................................................... 281

5.4.2. .............................................................................................283
- ............................................................................................. 284
- - ............................................................................................... 284
- .......................................................................................................... 285
- ........................................................................................... 288
- ...................................................................................................... 290
- ................................................................ 293
- ........................................................... 293
- - ....................................................................................... 294
- - ............................................... 297

5.4.3. ...............................................................................................................................297
- ............................................................ 297
- .............................................................................................. 300

5.4.4. . .............................................300
5.4.5. .............................................................................................................303
5.4.6. ...........................................................................................................................306
- ............................................................................................................. 307
- ............................................................................ 311
- ...................................................................................................... 312

5.5. . .........................................312
5.5.1. . ...................................................313
5.5.2. .........................................................................................314
5.5.3. .................................................................................................317
5.5.4. ..................................................................................................318
5.5.5. ..............................................................................................320
5.5.6. ..................................................................................322
5.5.7. .....................................................324
5.5.8. ......................................325
5.6. .............................................................................................326
5.6.1. ........................................................................................326
5.6.2. .........................................328
5.6.3. . .....................................330

5.6.4. k- ........................................................................333
5.7. .........................................................................334
5.7.1. ....................................................................................334
- ....................................................................................................... 334
- ............................................................................................................ 338
- ........................................................................... 340

5.7.2. ..............................................................................................340
- .................................................................................. 341

5.7.3. ............................................................................................343
5.7.4. ..................................................................................................................................346
5.7.5. , .......................................................................................348
- p- p- .......................................................................................................... 350

5.7.6. . ................................................353
5.8. ..............................................................................................354
5.8.1. . .................................................................354
- .................................................................. 355
- ................................................................... 355

5.8.2. ..................................................................................................355
5.9. ...............................................................................................................357
5.9.1. ........................................................................................................357
5.9.2. ..................................................................................................................363
6 . NP- ..........................................369
6.1. .............................................................................................369
6.1.1. .....................................................................................................369
6.1.2. ....................................................................................................370
6.1.3. ..........................................................................................................370
6.1.4. ..........................................................................................................................370
6.2. NP- ................................................................................................................373
6.3. .............................................................................................................374
6.3.1. ......................................................................376
6.3.2. .....................................................................................................380
6.3.3. - ....................................................................383
6.3.4. ...........................................................................................................385
6.3.5. ............................................................................................388
6.3.6. ...........................................................................391
6.3.7. ................................................................................................395
6.4. ...........................................................................398
6.4.1. ( ).............................................................398
6.5. ......................................................................................401
6.5.1. "X"- "O".....................................................................................................402
6.5.2. .........................................................................405
6.5.3. - ....................................................................................................406
6.5.4. - ...................................................408
6.6. ...............................................................................................................409
6.6.1. ........................................................................................................409
6.6.2. ..................................................................................................................413
- NP- ................................................................................................................ 413
- ........................................................................................................... 425

7 .......................................................................................427

7.1. K- ......................................................................427
7.2. .............................................................................................................................434
7.3. .......................................................................................445
7.4. ....................................................................................................450
7.5. ................................................................................................456
7.6. .........................................458
7.7. .................................................................................461
7.8. .............................................................................................464
7.9. ..........................................................................................466
7.10. ......................................................471
7.11. .......................................................................................................474
7.12. .............................................................................................................475
7.12.1. ......................................................................................................475
7.12.2. ................................................................................................................478
8 .........................................................................481
8.1. .............................................................................................................................481
8.2. ...........................................................................484
8.2.1. .....................................................................................................484
8.2.2. ..........................................................................................................495
8.2.3. ..............................................................................................497
8.2.4. . ...............................................504
8.2.5. ............................................................508
8.2.6. - ........................................................................................513
8.2.7. - ........................................................................517
8.2.8. ...................................................................................522
8.2.9. .................................................................................................526
8.3. ..............................................................................................528
8.3.1. .......................................................................................................528
8.3.2. .................................................................................................532
8.3.3. .............................................................................................................533
8.3.4. .................................................537
8.3.5. .....................................................539
8.3.6. .................................................................................540
8.3.7. ..........................................................................................542
8.3.8. ...........................................................543
8.3.9. ............................................................................................................548
8.3.10. .................................................................................................549
8.4. .................................................................551
8.4.1. .............................................................................................................552
8.4.2. ...............................................................................................................553
8.4.3. .......................................................................................................555
8.4.4. ....................................................559
8.4.5. ............................................................................................561
8.4.6. ...................................................................................................564
8.4.7. ............................................................................................565
8.4.8. .............................................................................................................568
8.4.9. ....................................................................................................571
8.4.10. .........................................................................................574

10

8.4.11. .............................................................................................................576
8.4.12. - ............................................................................................................579
8.4.13. ..............................................................................................582
8.5. ...............................................................................................................584
8.5.1. ........................................................................................................584
8.5.2. ..................................................................................................................591
9 ..................................595
9.1. ...............................................................................................................595
9.1.1. ...........................................................................................................596
9.1.2. ........................................................................598
9.1.3. .................................................................601
9.1.4. ...................................................................................604
9.1.5. .......................................................................................605
9.1.6. .....................................................................................607
9.1.7. ...............................................................................................608
9.1.8. . . ...........................................................610
9.2. .......................................................................................................616
9.2.1. ......................................................................617
- .......................................................................................... 618

9.2.2. ..........................................................................621
9.2.3. ..................................................................................................622
9.3. ........................................................................627
9.3.1. .........................................................................................628
9.4. ...............................................................................................................629
9.4.1. ........................................................................................................629
9.4.2. ..................................................................................................................633
10 ..............................................................................................637
10.1. ............................................................................................................................637
10.2. ........................................................................................................638
10.3. ................................................................................640
10.3.1. ...............................................................................................640
10.3.2. ................................................................................641
10.3.3. ........................................................................................643
10.3.4. ...........646
10.3.5. .................................................................................................646
10.3.6. .....................................................................................................648
10.3.7. .............................................................................................649
10.3.8. . .........................650
10.3.9. ............................................................................653
10.3.10. : PackBits ..............................................................655
10.4. ....................................................................................................656
10.4.1. - ......................................................................................656
10.4.2. ...............................................................................................660
10.4.3. .............................................................................671
10.4.4. K ......................................................................................................672
10.4.5. ............................................................................................673
10.5. ..............................................................................................681
10.5.1. ....................................................................683

11

10.5.2. ......................................................................................................686
10.5.3. : MNP-5...................................................................688
10.6. .......................................................................................................690
10.6.1. .....................................................................................................................691
10.6.2. ...........................................................................................................695
10.6.3. .............................................................................................696
10.6.4. ....................................................................697
10.6.5. LZ77. ..........................................................698
10.6.6. LZSS. ..............................................................................................698
10.6.7. FLZ. LZ77 ......................................................................................699
10.6.8. LZW. ................................................................................700
10.6.9. GIF. CompuServe .....................................................................706
10.6.10. ....................................................................707
10.6.11. ................................................................................708
10.6.12. LZW ..................................................................................................709
10.7. ..............................................................................................710
10.7.1. ..................................................................................710
10.7.2. JPEG ..............................................................................................................................711
10.7.3. . MPEG .......................................................713
10.7.4. ......................................................................................................................715
10.7.5. .......................................................................................716
10.8. .............................................................................................................717
10.8.1. ......................................................................................................717
10.8.2. ................................................................................................................725
...........................................................................................................................727
......................................................................................................733

12


(, ) , .
, , " " .
, ,
, "" Introduction to Algorithms Cormen, Leiserson
Rivest, .

, "-",
, . ,


. ,
.
-.

. ,
, ,
( "" ) .. ,
,
.
. ,
. ,
, , .
,
-
. " ",
,
, .
, . , ,
-, . , ,
, - , ..,
, ,
..,
, , , ,
.
.
,
.
, .
, , , .
, ,
, ,
.
1 2002

14

15

,

. , :

, ;
, -mail
.

, (
) ,
.
- ,
( )
.
!
, ,

. , :

;
, ;
;
.
! , !

,

3 2005 .

16

0
,
,
"Think of all the psychic energy expended in seeking a
fundamental distinction between 'algorithm' and 'program'".
~ Epigrams in Programming
[Adams-1980]
, ,
. ,
1975 ( ), -
, , , ,
. , ,
, , ,
.
, , .
,
, .
10 [, .] ,
,
, .
, -. ,
( ) computer science,
. -
, : ( : ),
(: informatique), (: informatik) .
informatics
, . , informatics
: ,
- computer science (
), Microsoft Word
.
:
(. International Olympiad in Informatics), (. Balkan
Olympiad in Informatics).
... ,
- ,
, .

0 - ,

18

0.1.

, - -
, 0.1. (
? ?)

0.1. .

0.1.1. -
, -
. , - . - ,
.
- :
, , .

0 - ,

19

, - .

.


- : " , , ". ,
: , , , , () ,
. , ,
,
, , , . (
0.1.1., 0.1.1. 0.1.1.).

0.1.1. : ,
.

0.1.1. -
: , .

0.1.1. , .

0.1.2.
, , , , . -

0 - ,

20

, ,
, ( ,
). , ,
, ,
() .
,
.


, , , , , . , . - , , . , ( . hacker,
hacking) ( . cracker, cracking) .
, .
( ),
, , .

, .

- .
, ,
, .

0.1.3.
10 .. .
- -
( -, - ,
).
, , .
, :
, .
,
.

0.1.4.
,
,
. ""- Maxis
.
, , . ,
, . -

0 - ,

21

0.1.5.
,
.
,
:
: ,
.
: ,
,
.

: (
)
( ). ,
, , ,
, .
- ,
, :
, .

, :
? , , , , .
- .
. -,
.
()
, ,
.
.
, .

0.1.6.

, ,
. , , .
, ,
: , ,
.
, ,
(
).
( ) (

0 - ,

22

). ()
, .


. ( -) "" .
- .
,
.


.
,
- .
.

0.1.7.
:
. , -
.
:
. ,
(, , , .).
,
. , ,
. , , ,
25 . ,
, .
,
. . :

( ).
,
, , :
, - (
) .

0 - ,

23

0.2.
( . lamer),
. , ,
, [-1989].
, - , ,
.
-, - , ,
, , .
, ,
.
, ,
:
i++; /* i */

e , , Minesweeper Windows
- ,
1 [Prize-2000].
, ,
. , ,
10 .
,
.
, , ( . garbage collector)
, Java,
, XX .
, , -
Google ,
.
, , + .
, , "
, (n2)", - (n3), n3 > n2.
, C , .
, ,
, .

, ,

, ,
A

,
, , .

. ,

0 - ,

24

, 10 10 , , 10 ,
10% -.
, brute-force- ftp ( . File Transfer Protocol
) , ,
hack- , - 5 (
), .
,
( /,
).
, , -
(, ).
, .
, :
0x000000FF & (i >> 24)

, , :

n n
m
f i n
m i 1

, . , , : ,
, .
, ,
. , -
, .
, , .

( ):
, .
, , ,
:
, .

0.3.
,
. , .
, ,
.

0.3.1.
alKhowarizmi, VIII
Aljabr wal muqabala (, -
). -
, :

0 - ,

25

Al-Khashi, XV
16 .
, , . , XII-
Al-*
, ,
, ,
[Knuth-1/1968].
,
, :

, ;

, .
( ) - ,
(, ). - ,
.
, .
. -,
,
.
,
, XX .

0.3.2.
300 . . . . , -
m n:
1)
2)
3)
4)

m - n, .
m : m n.
m 0, 1),
m n.
(- ) n.

250 . . . . , ,
- . , , 250 . . . . , ( ), .
: .
780-850 . , , Abu Ja'far Mohammed Ben
Musa al-Khwarizmi "Hisab al-jabr w'al-muqabala".
1424 . , Ghiyath al-Din Jamshid Mas'ud al-Kashi
16 .

0.3.3.
1845 . (Gabriel Lame ,
, ,
) , ,
5 - .

0 - ,

26

1910 . ,
.

0.3.4.
1900 .
( ) .
1920-30 . ,
.
1930 . -.
1936 . ,
, . (
, .)
.
XX ( )
, . , ,
. , ,
XXI ,
.
, ,
, , .

0.4. = ++

, .
:

;
;
C ,
;
, .

: , ,
? , :
1. = ++, = ++.
2. .
3. ++: ++
.

0.4.1.
-
.
( , , ),
,
, .

0 - ,

27

, , .
- (
- ).
,
, ++, Java. ( ) ,
.
, . ,
, "
".
,
. ,
, .
,
/ , . -
- , ,
.
( . , ,
.). - ( )
( -).

0.4.2.
1. " " - ,
, , .
2. " " - , , .
3. ""
4. "" "" .
, ( ) "" .
. , . , . , , .
5. " "
6. " . NP- "
7. " "
8. " "
9. " "
10. ""

0 - ,

28

0.4.3. C?
.
( upgrade ++) , , , . - (
) "- " Java.
, , "" ,
Java ( ).
: , "" , ( ). ,
( )
. ,
, -
,
.
, , , .
, ++? upgrade-
, . , ++ ,
, , . ,
: , ,
- , . , , Algorithms in Pascal, - , ++ Java. ++.
, ? , .
: - , -
, ,
- , -: - . , ,
. :
( ), ,
10 .
Delphi.
,
. informatics,
. Borland International
, .
Delphi .
Macintosh ( ,
) Linux, Unix .
: ++, Java, . , - Java, Javascript, Perl, PHP
- :
, .

0 - ,

29

0.4.4.
(, , , ..), , "" .
DOS ( Borland C++ 3.1),
Windows ( Visual C++ 6.0).
ANSI .
Windows, DOS, / .

0.5.

, , .
.

0.5.1.
, , , ,
.
, "
" ( ). ,
, .
SAP Labs Rila
Solutions .
, ( ),
- , ( , deadline
. 22:20 01:55 .).
. ( ). ( ) ,
, ,
(
.).
. , ,
.

, . , , , , , , , , ,
.

0 - ,

30

, , ,
.
- ( , . ).
( ), .
, .
, " " , bold ,
- .

0.5.2.
,
http://www.nakov.com/algoplus-bugs/submit-bug.php:
(20), (15), (12), (12),
(6), (5), (3), (3),
(3), (3), (3), (2),
(2), (2), (2), (2), (2),
(2), (2), (2), (2),
(2), (2), Ka (1), (1), (1),
(1), (1), (1), (1),
(1), (1), (1), (1),
(1), (1), (1) (1) .

0.5.3.

. , , , . , , , (, ) ( ).
:
http://www.facebook.com/groups/168112146541301
:
panayot.dobrikov@sap.com; dobrikov@gmail.com
nakov@cs.berkeley.edu; preslav.nakov@gmail.com
- ,
.
-
:
http://www.programirane.org
:
;
, ; ; ; ;
; - .

0 - ,

31

1

" :
, , , ."
~

1.1.

,
-.
,
- , .

1.1.1.
,
, , .
, , ,
,
. -. ,
.
.

-
. - .
, , () , , .
, , ,
, , ax2 + bx + c = 0 .
- :
A, B, C, ... . , ,
- ( ).
,
A a1, a2, ..., an
:
A = {a1, a2, ..., an}
, ai, i = 1,2,...,n, A aiA,
aiA. ( A - n),
|A|. n = 0, . -,
( 1.1.1.):

1 -

34

, (a, b, ) ,
, , .

A
a

1.1.1. .
, ,
[,-1973]. ,
-.
1.1. A B, A B. B ( 1.1.1.). , B , A
() B. B.

B
A

(a)

()

()

()

1.1.1. (), (), () () .


1.2. C A B,
a , aA aB. C = AB.
1.3. C = AB A B C,
, A B.
1.4. C = A\B A B C,
, A, B.
1.5. , .
.
-, .
, ,
. ():
{a, a, b} {a, b, b} {a, b, a} {a, b} {b, a}
1.6. , , .
1.7. n- , n- ().

1 -

35

n- , .
, (a, b, c) (a, c, b) ..
:
1. A = {1,2,4,5,7} B = {2,3,4,5,6}. :
AB, AB, A\B, B\A.
2. A B , AB = A.
B?
3. A B : AB = (AB) \ (AB).
A = {1,2,4,5,7} B = {2,3,4,5,6}.
4. , A B = B A.
: AB, AB, A\B, B\A, AB?

-
, . (
3 "" : , ),
.
. , , , .
1.8. ( N) , 0, 1, 2, 3, ....
, .
- :
, .
, N - , .
, n-
.
1.9. Z :
..., 3, 2, 1 ( ), 0 (), 1, 2, 3, ... ( ).
,
[-1995]. - ,
,
.
. ANSI C (American National Standards Institute [ANSIC])
( 1.1.1. Borland C DOS), , :
|short| |int| |long|

int ( , DOS
2 , Windows 4).
, unsigned, ,
: (unsigned)(-1).

1 -

36

char
unsigned char
short int
int
long int
unsigned short int
unsigned long int

128, ..., 127


0, ..., 255
32768, ..., 32767
32768, ..., 32767
2147483648, .., 2147483647
0, ..., 65535
0, ..., 4294967295

8
8
16
16
32
16
32

1.1.1a. Borland C DOS.


1.1.1a. ,
.
, . , ( ) , ( . overflow)
.
1.10. p/q, p q q . Q.
1.11. , :
x = n + 0,d1d2d3... ,
n , di 0 9. 0,d1d2d3...
. ,

d1 d 2
d
d
d
d
1

kk x n 1 2 kk k
10 100
10
10 100
10 10

kN, k 0.
, di .
(.. ) . 1/3 = 0,333333..... 3
. 1/3 = 0,(3) .
- , 1/7 = 0,(142857).
, , ..
p/q (p,qN, q > 0),
:
= 3,1415926535 ....
, 355/113, ,
( 6 )
. 22/7.
:
, [-1995]. , -
IEEE (Institute of Electrical & Electronics
Engineers). , .
1.1.1. Borland C DOS.

float
double
long double

3,4.1038 , ..., 3,4.1038


1,7.10308 , ..., 1,7.10308
3,4.104932 , ..., 1,1.104932

32
64
80

1 -

37

1.1.1. Borland C.
,
( . underflow):
( ,
).
: 1/3
.
, , - ( > 0) ,
( ), - ,
0.
:
, , .

- .
m n , m 0. q r (0 r <
m) , n = q.m + r. q n/m, r
. r , , m n (n
m) m|n. ( )
/ %. "",
:
q = n / m;
r = n % m;
1.12. (n m) % z = 0, , n m z
n m (mod z).

n. : ( )
n 10. , n . ,
n , , n
:
#include <stdio.h>
unsigned n = 4242;
int main(void) {
unsigned digits;
for (digits = 0; n > 0; n /= 10, digits++);
printf(" %u %u\n", n, digits);
return 0;
}

digits.c
:
1. m n, (m,n) : (7,3), (7,3),
(7,3), (7,3), (3, 7), (3,7), (3,7), (3,7).
2. m n (m 0) n = q.m + r, 0 r < m, (q, r ). [-1995]
3. .
?

1 -

38

-
a1, a2, ... , an. S = a 1 + a 2 + ... + an -
:
n

S ai ,
i 1

a ,

1i n

i 1..n

R(x), i
:
S ai
i:R ( x )

C Sn n :
unsigned sum(unsigned n)
{ unsigned i, s = 0;
for (i = 1; i <= n; i++) s += i;
return s;
}

sum1.c
a[] n :
int sum(int a[], unsigned n)
{ unsigned i;
int s = 0;
for (i = 0; i < n; i++) s += a[i];
return s;
}

sum2.c

:

Sn

n.(n 1)
2

,
.
:
n

a .b

(1)

j 1 i 1

a1 .b1 a1 .b2 a1 .bm a n .b1 ... a n .bm

a1 .(b1 ... bm ) a 2 .(b1 ... bm ) a n .(b1 .. bm ) (a1 ... a n ).(b1 ... bm )


n

j 1

i 1

a j . bi
, :
unsigned i, j;
int result = 0;
for (j = 1; j <= n; j++)
for (i = 1; i <= m; i++)
result += a[i] * b[j];

, , :

1 -

39

(2)

ij

i:R ( x ) j:S ( x )

(3) ai ai
R( x)

S ( x)

ij

j:S ( x ) i:R ( x )

i
S ( x )|| R ( x )

i
S ( x )&& R ( x )

S(x)||R(x) S(x)&&R(x) , S R, i j.
:

P = 1.a2.a3.....an , ,
n

P ai , P ai P ai
i 1

1i n

i 1..n

a[], n , :
int mult(int a[], unsigned n)
{ unsigned i;
int s = 1;
for (i = 0; i < n; i++) s *= a[i];
return s;
}

mult.c
:
1. .
2. (1), (2) (3) .
3. , (1), (2) (3).
4. (1), (2) (3), :

i 1..n

i n..m

ai a n

,1nm

i 1..m

- , , n-
1.13. x , y , :
xy = x.x. ... .x
(y )
y < 0, xy = 1 / x-y.
(x 0):

xy = xy-1.x
xy = xy+1/x
xy1+y2 = xy1.xy2
xy1.y2 = (xy1)y2

xy y :
double power(double x, unsigned y)
{ double res = x;
unsigned i;
for (i = 1; i < y; i++) res *= x;
return res;

1 -

40

power.c
- ( 7.5.) , - xy.
xn = y (n , n > 1), x n- y
x n y . , y n- y .
n = 2, y y
y . ,
:
p

xq xp
q

- , x y (x > 1). y
y = d,d1d2d3 ... :
d

d
d1 d 2

kk
10 100
10

xy x

d
d1 d 2
1

kk k
10 100
10 10

, xy
, k.
, , - . y = bx b 1, b >
0, y > 0 x. y b
logb y. (x > 0, y > 0, b > 0, b 1, c
> 0, c 1):

x b logb x log b b x

(1)

log b ( xy ) log b x log b y

(2)

log b x y y. log b x

(3)

log b x

log c x
log c b

(4)

- , 2
log x log2 x. ln x
log x: H e = 2,71828... ( 1.1.6.)
:
1. - , .
2. (1), (2) (3) , .

- .
n, nN ( n!) 1 n:
n

n! 1.2...n i ,
i 1

0! = 1.
C n! :
unsigned long factoriel(unsigned n)
{ unsigned i;
unsigned long r = 1;

1 -

41

for (i = 2; i <= n; i++) r *= i;


return r;
}

fact.c
-
.
,
.
:

1, n 0
n!
n.(n 1)!, n 0
n Sn :
0, n 0
Sn
S n 1 n, n 0
- ( 1.2.),
.
:
1. x y (xR, yN).
2. -
.

-
(
).
m n (mn) : .. ,
m n (n 1, m 1). m = n .
aij : ,
, ( 1.1.1.).

Amn =

11

12

...

1n

a21

22

...

a2n

am2

...

amn

m1

1.1.1. mn.
, , , 22, 33, 44 , (
) . - [Ayres-1962].
:
int A[m][n];

1 -

42

- ,
struct data, :
struct data {
int a;
int b;
...
} A[m][n];


/ -
. - ( 1.1.1.).
11

12

...

1n

11

12

...

1 n

a21

22

...

a 2n

a21

22

...

a2 n

am2

...

amn

m1

a m2

...

m1

a mn

a)

1.1.1. : () () .
/*
for (i = 0; i <
for (j = 0; j
scanf("%d",
/*
for (i = 0; i <
for (j = 0; j
scanf("%d",

*/
m; i++)
< n; j++)
&A[i][j]);
*/
n; i++)
< m; j++)
&A[j][i]);

/* */
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++)
printf("%.3d", A[i][j]);
printf("\n");
}

matrix.c

Amn Bmn Cmn , cij = aij + bij ( i = 1, 2,...,
m, j = 1, 2, ..., .n), 1.1.1.
11

12

...

1n

a21

22

...

a2n

b11

b12

...

b1n

b21

b22

...

b2n

m1

am2

...

amn

...

1n+ b1n

a21+ b21

22+ b22

...

a2n+ b2n

am2+ bm2

...

amn+ bmn

...

12+ b12

Cmn =

11+b11

b m1

bm2

...

bmn

m1+bm1

1.1.1. .
for (i = 0; i < m; i++)

1 -

43

for (j = 0; j < n; j++)


C[i][j] = A[i][j] + B[i][j];

summat.c

Amn Bnp Cmp, :

cij aik .bkj , i = 1,2,...,m j = 1,2,...,p.


n

k 1

-, m.p.n
. n > m n > p, n3.
for (i = 0; i < m; i++)
for (j = 0; j < p; j++) {
C[i][j] = 0;
for (k = 0; k < n; k++)
C[i][j] += A[i][k] * B[k][j];
}

multmat.c

, , . , nlog 7 ( n2,81) , . , , 7.6., .
:
1. unsigned a[MAX][MAX].
void fillMatrix(unsigned a[][MAX], unsigned n),

a[][] :
0
1
2
3
4

20
0
5
6
7

19
18
0
8
9

17
16
15
0
10

14
13
12
11
0

2. unsigned a[MAX][MAX]. , , n = 5 :
1
2
3
4
5

16
17
18
19
6

15
24
25
20
7

14
23
22
21
8

13
12
11
10
9

1.1.2.
: a1, a2, ..., an. P = a 1.a2..an.
, ai = i, i = 1,2,...,n, P = 1.2 ... n = n!.

1 -

44

,
1.1.1., .
n!. n! ,
-. 10! e 3628800, . 20!
C.
- , ,
, :
P 1 log a , [x] -
10 i
n

i 1

, - x.
, ,
P [1+log10(P)], :
log P = log(a1.a2. an) = log a1 + log a2 + + log an.
n!
#include <stdio.h>
#include <math.h>
const unsigned long n = 123;
int main(void)
{
double digits = 0;
unsigned i;
for (i = 1; i <= n; i++)
digits += log10(i);
/* [x] , unsigned long */
printf(" %lu! %lu\n", n, (unsigned long)digits+1);
return 0;
}

digitsnf.c
:
, P
[1+log10(P)].

1.1.3.

.
, ..
1.14. ,
1 , 1 . , .
:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
( 300 . ...), .
,
, ( ).
( RSA [RSA-78])
.
, , .
55,
5 11. 4853 (211 23),

1 -

45

, .
100
, ,
, (, ,
).
, :

[a, b]?
?
n- ?

(x) ,
x, (x)
. (
6.2.), (x), (
, ln x loge x):
( ) (x) x / ln(x a),
, - x.
- = 1.
. n- [n.ln(n)]. -
[n(ln(n) + ln(ln n 1))].
. x 1/ln(x).
,
[Primes-1][Primes-2]:

1. n > 2 .
2. n > 17 .
3. -
.
4. n > 5 .
5. .
. n2+m2 n2+m2+1.
. n2+1.
. () n2 (n+1)2 .
:
1. (x) , -?
2. .
3. .

-
, , :
[2,

p
2

1] p , , , p .

1 -

46

,
, ,
- .
(). p , (p1)! 1 (mod p).
(p1)!, -

1 .

1:


p x, x >
-

p (). , ,

p , , p p = x.y, y <

p , ..

p . :

#include <stdio.h>
#include <math.h>
const unsigned n = 23;
char isPrime(unsigned n) /* 1, , 0 */
{ unsigned i = 2;
if (n == 2) return 1;
while (i <= sqrt(n)) {
if (n % i == 0) return 0;
i++;
}
return 1;
}
int main(void) {
if (isPrime(n))
printf(" %u .\n", n);
else
printf(" %u .\n", n);
return 0;
}

prime.c
: , p ,
, [2, p ]
( , ). ,
k ( Pi, i = 1,2,,k),
[2, (Pk )2] . C:
#include <stdio.h>
const unsigned n = 23;
/* , */
#define K 25
unsigned prime[K] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
/* , *
prime[] */
char checkprime(unsigned n)

1 -

47

{ unsigned i = 0;
while (i < K && prime[i] * prime[i] <= n) {
if (n % prime[i] == 0) return 0;
i++;
}
return 1;
}
int main(void)
{ if (checkprime(n))
printf(" %u . \n", n);
else
printf(" %u . \n", n);
return 0;
}

preproc.c
:
1. ,
. (p1)!, ,
p?
2. , , p , ,
[2, p ].

- .
: , - n.

- n . n , k
- k .
, , -
, " ".
(275-195 . . .) ,
. ,
.
, ,
, [, , -1995]
[, , -1980]. ,
, , . , .

1 -

48

1.1.3. .
: ,
( ).
:
2 n :
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... , n
2. ,
:
(2), 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... , n
-, :
3. , 3:
(2), (3), 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... , n
, 5 5-:
(2), (3), 4, (5), 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... , n
"" , i . ,
,
. -
:

1)

2)
3)
4)

sieve[] . -, ,
1. - i,
(.. ). i = 2.
i, sieve[i] 0. i e .
M 1 sieve[k], k = i, 2i, 3i, , (n/i).i (..
i ).
i n, 2, .
#include <stdio.h>
#define MAXN 30000
/* n */

1 -

49

const unsigned n = 200;


char sieve[MAXN];
void eratosten(unsigned n)
{ unsigned j, i = 2;
while (i <= n) {
if (sieve[i] == 0) {
printf("%5u", i);
j = i * i;
while (j <= n) {
sieve[j] = 1;
j += i;
}
}
i++;
}
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) sieve[i] = 0;
eratosten(n);
return 0;
}

sieve.c
:
2
59
137

3
61
139

5
67
149

7
71
151

11
73
157

13
79
163

17
83
167

19
89
173

23
97
179

29
101
181

31
103
191

37
107
193

41
109
197

43
113
199

47
127

53
131

- .
( sieve[N]) , .
preproc.c
prime[], k ,
[2, (Pk )2] . :
, . ,
2 [3, 22] 3
. -, 3,
[4, 32] 5 7, .
, prime[] ,
[2, n] . :
#include <stdio.h>
#define MAXN 10000
/* n */
const unsigned n = 500;
unsigned primes[MAXN], pN = 0;
char isPrime(unsigned n)
{ unsigned i = 0;
while (i < pN && primes[i] * primes[i] <= n) {
if (n % primes[i] == 0) return 0;
i++;
}
return 1;

1 -

50

}
void findPrimes(unsigned n)
{ unsigned i = 2;
while (i < n) {
if (isPrime(i)) {
primes[pN] = i;
pN++;
printf("%5u", i);
}
i++;
}
}
int main(void) {
findPrimes(n);
printf("\n");
return 0;
}

rproc.c
, n ,
. [a,b] a (a>>1), - .
2, 3 5.
:
n = 30.q+r, r [0..29] r[0, 1, 2, ..., 14, 15].
30.q = 2.3.5.q
30 8. . .
4k/15 , :
30.q1, 30.q7, 30.q11, 30.q13
.
:
1. : 3) k = i2, i .
. .
2. .
3. , 4 .

-
( ) P (P>1)
() P1q1. P2q2. .Pnqn, P1 < P2 <
< Pn P , a qi . [-1995].
:
520 = 23.51.131
64 = 26
2345 = 51.71.671

1 -

51

A , ( 2 1.1.5.), :
P.
1) i = 2.
2) k = 0. P i, k .
3).
3) k > 0, ik .
4)
4) P > 1, i 2).
, . :
#include <stdio.h>
unsigned n = 435; /* , */
int main(void) {
unsigned how, i, j;
printf("%u = ", n);
i = 1;
while (n != 1) {
i++;
how = 0;
while (0 == n % i) {
how++;
n = n / i;
}
for (j = 0; j < how; j++)
printf("%u ", i);
}
printf("\n");
return 0;
}

numdev.c
:
.

- ,
: a1, a2, ..., an. ,
P = a 1.2. ... .an.
1.1.2., . ,
: , , 2 5,
, 2, , 5.
, , :
1) i (i = 1, 2,..., n) ai ai = 2Mi.5Ni.bi, bi % 2 0, bi % 5
0.
2)

M i Ni

P = 2i 1.. n .5i 1.. n .c , (c ), a



, :
25, 4, 20, 11, 13, 15

i 1

i 1

Mi Ni .

1 -

52

:
20.52.1, 22.50.1, 22.51.1, 20.50.11, 20.50.13, 20.51.3,
4 . :
25.4.20.11.13.15 = 4290000.
- .

.
n!.
[log 5 n ]
n . - ,

k
k 1 5
2 5 n .
#include <stdio.h>
const unsigned n = 10;
int main(void) {
unsigned zeroes = 0, p = 5;
while (n >= p) {
zeroes += n / p;
p *= 5;
}
printf(" %u! %u\n", n, zeroes);
return 0;
}

factzero.c
:
1. ,
.
2. , .
3. , n!

1.1.4.
-
1.15. ,
2p1, p e .
39 p, 2p1 :
2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941,
11213, 19937, 21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433, 1257787, 1398269,
2976221, 3021377, 6972593, 13466917
37 p 37
. ( 1999 2001 .),
38- 39-, ,
-. p. .. - .
: , . ,
. 23- 1963 .,
,

1 -

53

"2112131 " (
1.1.4.).
- , , :
2134669171 8107892 (??39- M )
269725931 2098960 (??38- M )
230213771 909526 (37- M )
229762211 895932 (36- M )
213982691 420921 (35- M )
- , . ,
(
-).
- : , ""
38- , $50000.
$250000 [Primes-3].

1.1.4. 211213-1 .
:
p = 2, 3, 5, 7, 11, = 2p 1 .
, .
1870 , - ,
( e -
[Guinier-1991]).
(LucasLehmer Test, 1930) :
:
1 = 4
n+1 = (En )2 2
:
4, 14, 194, 37634, .
(-). m = 2p 1 ( p )
, :
(Ep1) % (2p 1) = 0
.
.
:
1. n ,
-.
2. n ,
-. .
3. 2n1 , n ?

1 -

54

- .
1.16. n ,
( n ).
3 :
6 = 1 + 2 + 3,
28 = 1 + 2 + 4 + 7 + 14,
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248.
:
8128, 33550336, 8589869056,
, ( n = 1,
2, 3, ), 5-
. :
. () 2p1 , 2p1.(2p1) .
n : pi n
( 10 2, 3, 5, 7, 13, 17, 19, 31, 61, 89). ,
n,
. ,
: 2
. number[]:
.
: number[k-1] ( k ),
number[k-2] .. k- number[0].
, number[], :
i = 0; number[i]++;
while (10 == number[i]) { number[i] = 0; number[++i]++; }
if (i == k) k++;

2,
, .. 9, , while(10 == number[i]), .
, :
unsigned i, carry = 0, temp;
for (i = 0; i < k; i++) {
temp = number[i] * 2 + carry;
number[i] = temp % 10;
carry = temp / 10;
}
if (carry > 0) number[k++] = carry;

, 10 , mPrimes[]:
#include <stdio.h>
#define MN 10
unsigned mPrimes[MN] = { 2, 3, 5, 7, 13, 17, 19, 31, 61, 89 };
unsigned k, number[200];
void doubleN(void)
{ unsigned i, carry = 0, temp;

1 -

55

for (i = 0; i < k; i++) {


temp = number[i] * 2 + carry;
number[i] = temp % 10;
carry = temp / 10;
}
if (carry > 0)
number[k++] = carry;
}
void print(void)
{
unsigned i;
for (i = k; i > 0; i--)
printf("%u", number[i-1]);
printf("\n");
}
void perfect(unsigned s, unsigned m)
{
unsigned i;
k = 1; number[0] = 1;
for (i = 0; i < m; i++)
doubleN(); /* 2^i */
number[0]--; /* {2,4,8,6} */
for (i = 0; i < m - 1; i++)
doubleN();
printf("%2u-o = ", s);
print();
/* */
}
int main(void) {
unsigned i;
for (i = 1; i <= MN; i++)
perfect(i, mPrimes[i - 1]);
return 0;
}

perfect.c
:
1-o
2-o
3-o
4-o
5-o
6-o
7-o
8-o
9-o
10-o

=
=
=
=
=
=
=
=
=
=

6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176
191561942608236107294793378084303638130997321548169216

: - (,
). , ,
(- ). , ,
300 .
:
1. , ( 1
) 2. , 6 : 1/1 + 1/2 + 1/3 + 1/6 = 2.

1 -

56

2. , ,
( 1 ) 2. ?

1.1.5. , .

1.17. n- .
k-
:

n
n.(n 1)...(n k 1)
C kn
k (k 1)...1
k

()

, C k n -
k
n

, n,
. .
n , (*) :

n
n!
C kn
(**)
k!(n k )!
k
, ,
n k ( 1.3.3.) (?).
, (a+b)n, :
n
n
n
n
n
a bn a nb0 a n1b1 ... a 0b n a nibi
0
1
n
i
i 0



, [Knuth1/1968]. .
1.1.5. C k , 0 k n < 10.
n

n
0
1
2
3
4
5
6
7
8
9

n
0

1
1
1
1
1
1
1
1
1
1

n
1

0
1
2
3
4
5
6
7
8
9

n
2

0
0
1
3
6
10
15
21
28
36

n
3

0
0
0
1
4
10
20
35
56
84

n
4

0
0
0
0
1
5
15
35
70
126

n
5

0
0
0
0
0
1
6
21
56
126

n
6

0
0
0
0
0
0
1
7
28
84

n
7

0
0
0
0
0
0
0
1
8
36

n
8

0
0
0
0
0
0
0
0
1
9

n
9

0
0
0
0
0
0
0
0
0
1

1.1.5. .
, - 1.1.5., :

1 -

57

n n
1
0 n
n n

k
n

(1)
(2)

n n 1 n 1

k k k 1

(3)

1.1.5. - ,
:
n=0
n=1
n=2
n=3
n=4
n=5

1
1
1
1
1
1

3
4

1
2

1
3

6
10

1
4

10

1
5

...
1.1.5. .
1 ( (1) (2)),
( (3)). n-
, (n1)- . C k n
n

, n- k-
C k . , i
n

i1, .
:
lastLine[], n k C k
n
.
#include <stdio.h>
/* */
#define MAXN 1000
const unsigned n = 7;
const unsigned k = 3;
unsigned long lastLine[MAXN + 1];
int main(void) {
unsigned i, j;
lastLine[0] = 1;
for (i = 1; i <= n; i++) {
lastLine[i] = 1;
for (j = i - 1; j >= 1; j--)
lastLine[j] += lastLine[j - 1];
}
printf("C(%u,%u) = %lu\n", n, k, lastLine[k]);
return 0;
}

pascalt.c

1 -

58

, (*)
.
(**) n! k!(nk)!,
, : n = 100 k =
2 100! 2!.98! ( 150 ), C 2 4950.
100

2 C k ( )
n
1)

2)
3)

C 3 . (*) 7
, .
: 7! = 1.2.3...7 =
1.2.3.22.5.(2.3).7 = 24.32.51.71.
: 3!.(73)! = 1.2.3. 1.2.3.22 = 24.32.
4 2 1 1
1 1
: 2 .3 .5 .7 5 .7 .
4 2

2 .3

4)


: 51.71 = 35.

2.
#include <stdio.h>
#define MAXN 500
unsigned long n = 7;
unsigned long k = 3;
unsigned long pN, primes[MAXN], counts[MAXN];
void modify(unsigned long x, unsigned how)
{ unsigned i;
for (i = 0; i < pN; i++)
if (x == primes[i]) {
counts[i] += how;
return;
}
counts[pN] = how;
primes[pN++] = x;
}
void solve(unsigned long start, unsigned long end, unsigned long inc)
{ unsigned long prime, mul, how, i;
for (i = start; i <= end; i++) {
mul = i;
prime = 2;
while (mul != 1) {
for (how = 0; mul % prime == 0; mul /= prime, how++);
if (how > 0)
modify(prime, inc * how);
prime++;
}
}
}
unsigned long calc(void)
{ unsigned i, j;

1 -

59

unsigned long result = 1;


for (i = 0; i < pN; i++)
for (j = 0; j < counts[i]; j++)
result *= primes[i];
return result;
}
int main(void) {
printf("C(%lu,%lu)= ", n, k);
pN = 0;
if (n - k < k) k = n - k;
solve(n - k + 1, n, 1); /* (nk+1),...,n */
solve(1, k, -1);
/* 1,...,k */
printf("%lu\n", calc());
return 0;
}

cnk.c
( , ..
)
C k , , ,
n

.
: "" :

n n

k n k
, .
:
1. (1), (2) (3), . , (1) :
n
n!
n!
C 0n

1
0!(n 0)! 0! n!
0

n
n!
n!
C nn

1
n
n
!
(
n

n
)!
n
!0!

2. (1), (2) (3).
3. 1 (pascalt.c) C k
n

lastLine[] n+1 , - n,

. : ,
, 1 i, 1 k,
- . , k
n, (2) C n k , C k .
n

1.1.6.
-
.
, - -

1 -

60

.
0, 1, 2, 3, 4, 5, 6, 7, 8 9, (
,
- , .).
, , .
( 10 ). , ( 0 1) ( ) . , p p < 0,
.
, .
0 1. 11(10) 1011(2) (
, .).
16 . ,
0 9 , A, B, C, D, E
F, 10, 11, 12, 13, 14 15. 254(10)
FE(16).
, e = 2,718281828... ( .
n

1
an 1 n). -
n
.
e (
),
3 2.
, 3 - e.
. 0 0 V, 1 5 V. . , , ,
1960 . , 1, 0 1.
, 16 2 (16=24).
0 15 4 ( 0 1). - 8 .
, 0 255, .. 256 .
256 = 162,
.
- (4 ),
,
. - ,
10101000110111(2) . :
10 | 1010 | 0011 | 0111

:
0010 | 1010 | 0011 | 0111


2A37(16).
,
( ). -
- .
,
. , 153 ,

1 -

61

6. , 1, 5 3, ,
3, 3 , 0, 1 2.
- , -, .
, .. , . 123 3 3, 34 30. ( 1.1.7.),
.
- : . -. , -
p, p . anan-1...a0 (p), i (1 i n) .
:
A = anpn + an-1pn-1 + ... a 1p + a0
,
-.
:
1. 0 1?
2. 17 17 : 2; 8; 16.
3. 17 17 2; 8; 16.
4. ,
: 111, 110100, 1110100101, 10010101, 10101010101 10111110101.
5. , : 11, 11001, 1010101, 111111, 1010101000, 10101101000 11010111000.
6. ?
7. 17 17 .

- p-
,
p- : A p
, A 0, ,
(?). 29
( ):
29:2=14:2=7:2=3:2=1:2=0
1
0
1
1
1

: 29(10) = 11101(2).
convert()
:
char getChar(char n) /* , n */
{ return (n < 10) ? n + '0' : n + 'A' - 10; }
void reverse(char *pch)
{ char *pEnd;
for (pEnd = pch + strlen(pch) - 1; pch < pEnd; pch++, pEnd--) {
char c = *pch;
*pch = *pEnd;
*pEnd = c;

1 -

62

}
}
void convert(char *rslt, unsigned long n, unsigned char base)
/* n (n >= 0) */
/* base */
{ char *saveRslt = rslt;
while (n > 0) {
*rslt++ = getChar((char)(n % base));
n /= base;
}
*rslt = '\0';
reverse(saveRslt);
}

base.c
- 1, ,
p.
A p- : A p, . 0,125 :
0,125.2=0,25.2=0,5.2=1,0

0,125(10) = 0,001(2). A
p- () . .
convertLessThan1() A (0 < 1) cnt
, .
void convertLessThan1(char *rslt,
double n,
unsigned char base,
unsigned char cnt)
/* 0 <= n < 1 base
cnt */
{
while (cnt--) {
/* 0? */
if (fabs(n) < EPS) break;
/* */
n *= base;
*rslt++ = getChar((char)(int)floor(n));
n -= floor(n);
}
*rslt = '\0';
}

base.c
> 1 0 <
1, ,
, . convertReal():
void convertReal(char *rslt, double n,
unsigned char base, unsigned char cnt)
/* n base */
{ double integer, fraction;

1 -

63

/* */
if (n < 0) {
*rslt++ = '-';
n = -n;
}
/* */
fraction = modf(n, &integer);
/* */
convert(rslt, (unsigned long)integer, base);
/* ( ...) */
if ('\0' == *rslt) *rslt++ = '0';
else rslt += strlen(rslt);
*rslt++ = '.';
/* */
convertLessThan1(rslt, fraction, base, cnt);
if ('\0' == *rslt) {
*rslt++ = '0';
*rslt = '\0';
}
}

base.c
:
1. 157 : 3;5;7;14.
2. 0,321 : 3;5;7;14.
3. 157,321 : 3;5;7;14.
4. p- .
5.
p- .

- p- .

p- A,
. , , 12734(8), :
12734(8) = 1.84 + 2.83 + 7.82 + 3.8 + 4 = 5596(10)

, 10 . , 8,
. - ,
n- n
. (1) (2).
(1)
(2)

Pn(x) = a 0xn+a1xn-1+...+a n-1x+an


Pn(x) = an+x(an-1+x(an-2+...+x(a2+x(a1+xa0))...))

calculate():

1 -

64

char getValue(char c) /* c */
{ return (c >= '0' && c <= '9') ? c - '0' : c - 'A' + 10; }
unsigned long calculate(const char *numb, unsigned char base)
/* numb,
base, numb >= 0 */
{ unsigned long result;
for (result = 0; '\0' != *numb; numb++)
result = result*base + getValue(*numb);
return result;
}

base.c
, 1.
. , p.
double calculateLessThan1(const char *numb, unsigned char base)
/* numb (0 < numb < 1),
base */
{ const char *end;
double result;
for (end = numb + strlen(numb) - 1, result = 0.0; end >= numb; end--)
result = (result + getValue(*end)) / base;
return result;
}

base.c
, ,
:
double calculateReal(char *numb, unsigned char base)
/* numb,
base */
{ char *pointPos;
char minus;
double result;
/* */
if ('-' == *numb) {
minus = -1;
numb++;
}
else
minus = 1;
if (NULL == (pointPos = strchr(numb, '.')))
return calculate(numb, base); /* */
/* */
*pointPos = '\0';
result = calculate(numb, base);
*pointPos = '.';
/* */
result += calculateLessThan1(pointPos+1, base);
return minus*result;

1 -

65

base.c
:
1. 126(8); 10101(2); 3F2B(16); 3CB(14).
2. 0,233(8); 0,01(2); 0,34(16); 0,2A(14).
3. 126,233(8); 10101,01(2); 3F2B,34(16); 3CB,2A(14).
4. p-
.

1.1.7.
- , , : .
, . , , , . .
[1;3999] 7
( ): I(1), V(5), X(10), L(50), C(100), D(500)
M(1000). 1989 MCMLXXXIX.

-
. , - -,
. :
XI = 10 + 1 = 11
IX = 10 1 = 9
- .
,
- - .
1.1.7.
1(I)

2(II)

3(III)

4(IV)

5(V)

6(VI)

7(VII)

8(VIII)

9(IX)

10(X)

20(XX)

30(XXX)

40(XL)

50(L)

60(LX)

70(LXX)

80(LXXX)

90(XC)

100(C) 200(CC) 300(CCC) 400(CD) 500(D) 600(DC) 700(DCC) 800(DCCC) 900(CM)

1.1.7. .
1.1.7. . , , . ,
, 3(III), 30(XXX) 300(CCC). 7(VII), 70(LXX)
700(DCC). , , . ,
( )
, ,
, , .
- , . ,
- decimal2Roman().

1 -

66

:
const char *roman1_9[]={"", "A", "AA", "AAA", "AB", "B", "BA", "BAA", "BAAA",
"AC"};
const char *romanDigits[] = {"IVX", "XLC", "CDM", "M" };

A, B C
1.1.7., .
void getRomanDigit(char *rslt, char x, unsigned char power)
{ const char *pch;
for (pch = roman1_9[x]; '\0' != *pch; pch++)
*rslt++ = romanDigits[power][*pch - 'A'];
*rslt = '\0';
}
char *decimal2Roman(char *rslt, unsigned x)
{ unsigned char power;
char buf[10];
char oldRslt[MAX_ROMAN_LEN];
for (*rslt = '\0', power = 0; x > 0; power++, x /= 10) {
getRomanDigit(buf, (char)(x % 10), power);
strcpy(oldRslt, rslt);
strcpy(rslt,buf);
strcat(rslt,oldRslt);
}
return rslt;
}

rom2dec.c
:
1. : 10; 19; 159; 763; 1991; 1979; 1997; 2002.
2. : 0; 10; 0,28; 3,14; 1/7.
3.
.

-
-. -, , . ,
- , , , .
, 2 :
if (value > old) rslt -= 2*old;

19(XIX) I ,
21(XXI) .
:
roman2Decimal() ?
, .
.
.
unsigned roman2Decimal(const char *roman, char *error)
{ unsigned rslt, value, old;

1 -

67

const char *saveRoman = roman;


char buf[MAX_ROMAN_LEN];
old = 1000; rslt = 0;
while ('\0' != *roman) {
switch (*roman++) {
case 'I': value =
1; break;
case 'V': value =
5; break;
case 'X': value =
10; break;
case 'L': value =
50; break;
case 'C': value = 100; break;
case 'D': value = 500; break;
case 'M': value = 1000; break;
default:
*error = 1;
return (unsigned)(-1);
}
rslt += value;
if (value > old)
rslt -= 2*old;
old = value;
}
return (*error = strcmp(saveRoman,decimal2Roman(buf,rslt)))
? (unsigned)(-1) : rslt;
}

dec2rom.c
:
1. : DCLXXXIV, DCCLXIV, LX,
LXX, LXXX, XL, XXL, XXXL.
2.
.
3.
, .
1.1.7.

1.2.
: , . UNIX
"" ( GNU GNU is Not UNIX, WINE
WINE Is Not an Emulator, .).
1.18. , , .
- : ,
.
.
,
, .
.
P , , . -

1 -

68

- : P1 P2, P2 P3, , Pn
P1. , P1, P2, P3, ..., Pn, () .

:

, , , ()
. .
, ,
, ..
( ), . ,
.
"" ,
.. (, , ,
.).

, , .

1.2.1.
, ,
1.1.1. , , ,
:

n = 0 1.
n1 n.

( n 0 ).
C, n!:
#include <stdio.h>
const unsigned n = 6;
unsigned long fact(unsigned i)
{ if (i < 2) return 1;
return i * fact(i - 1);
}
int main(void) {
printf("%u! = %lu \n", n, fact(n));
return 0;
}

factrec.c
n
( 1.1.1.):
unsigned long sum(unsigned n) {
if (0 == n) return 0;
else return n + sum(n - 1);
}

1 -

69

:
,
, () , -, . ( 1.2.2.)
, :
,
. - n.sizeof(unsigned)
n . : n! 1.1.1. , , .. - .
, n!
- unsigned long,
.

1.2.2.

. ,

, , , , .

1.2.2. .
, ,
. ? ,

1 -

70

, .
, , , ,
, . ,
: ,
, ,
, ( 1.2.2.) ,
.
K ?
:
0,1,1,2,3,5,8,13,21,34,55,89,...,

,
0 1, .. :
F0 = 0,
F1 = 1,
Fi = Fi-1 + Fi-2

1.2.2. .
( ),
(Filius Bonaccii, .. ), 1202 .
Liber Abacci ( ) .
,
:

;
;
.

, , 3 ,
5 ( ,
), 8 .. , . ( 1.2.2.).

1 -

71

1.2.2. .
- 1611 . , ,
( 1.2.2.). , - ,
, - ,
.

1.2.2. .
? , - (
, ). -, 1845 .

( 1.2.3.) - .

.

1 5
1,61803
2

- .
A B, :

1 -

72

A A B

B
A
- ,
XIX- : .
,
.
- .
, ,

. ( 1.2.2.)
:
, , , 1, 0. ,
-
.

1.2.2. .
- , n- ,
, - :
unsigned long fib(unsigned n)
{ if (n < 2) return 1;
else return fib(n - 1) + fib(n - 2);
}

fibrec.c
, . , n = 40.
, ( n = 0 1),
. . ,
-
( 1.2.2.).

1 -

73

1.2.2. .
, . , , ..
. , F10
F8 F10 = F9 + F8 F9 = F8 + F7.
- -.
- , , .
( memoization) 8 .
, , : ,
. , :
unsigned long fibIter(unsigned n)
{ unsigned long fn = 1, fn_1 = 0, fn_2;
while (n--) {
fn_2 = fn_1;
fn_1 = fn;
fn = fn_1 + fn_2;
}
return fn_1;
}

fib2.c
,
:
unsigned long fibIter2(unsigned n)
{ unsigned long f1 = 0, f2 = 1;
while (n--) {
f2 = f1 + f2;
f1 = f2 - f1;
}
return f1;
}

fib2.c
, n , - . , n ?

1 -

74

,
( 1.4.8.):

Fn

n
1 1 5

.
5 2

n
1 5

-
n- .
, - , . n , ( 7.3.,
[-1998c]). , 5 .
, , .
n-
8 ( 8.1.), .
:
1. ,
.
2.
n- : .

1.2.3. - .
- ()
.
1.19. a b. , d - b, , a b.
, :
1)
2)

d|a, d|b
d1|a d1|b, d1|d.

: d|a , d
a . :
d1 a b d.
- a b (a,b) (a,b).
: (12, 8) = (8, 12) = (8, 4) = 4, (1, 10) = (7, 10) = 1.
1.20. 1,
.
- :
(a1, a2, ..., an) = ((a1, a2, ..., an1), an)
(a,b), . :
1)
2)

a > b, 4), 2).


a = b , (a,b) b
. a b 3).

1 -
3)
4)

75

b = b a 1).
a = a b 1).

- , ,
, -. (
):

a b, q1 r1. -
b , r1 r2 ..,
:
a = q1.b + r1
b = q2.r1 + r2
r1 = q3.r2 + r3
...
rk1 = qk+1.rk + rk+1, rk+1 = 0
rk . , :
(a, b) = (b, a % b)
b = 0 ( (a, 0) = a)
, ,
b 0 .
( ) - :
unsigned gcd(unsigned a, unsigned b)
{ unsigned swap;
while (b > 0) {
swap = b;
b = a % b;
a = swap;
}
return a;
}

gcditer.c
unsigned gcd(unsigned a, unsigned b)
{ return (0 == b) ? a : gcd(b, a % b);
}

gcdrec.c
, - .
: , .

, , x y (x, yZ), , :
d = (a,b) = ax + by
:
1. : (10,5); (5,10); (15,25); (25,15); (7,8,9); (3,6,9); (158,128,256);
(64,28,72,18).

1 -

76

2. .
10/15 2/3.
3. , (a1, a2, ..., an) = ((a1, a2, ..., an1), an).
4. .
5. , (a, b) = (b, a % b).
6. ,
a b, x y (x, yZ), (a,b) = ax + by?
7. ,
.
2; 5; 100; 1000 .
8. ( ) a, b c , a, b
c , c > a > b, c a + b 1, - ,
. d , d 0 < d a.
, / .

1.2.4. -
1.21. a b. d (d >
0) , a|d b|d - () a b.
- a b (a,b) [a,b].
: [6, 15] = [15, 6] = 30, [1, 10] = 10, [5,10] = 10, [5, 12] = 60.
,
:
(a1, a2, ..., an) = ((a1, a2, ..., an1), an)
- ,
, :

(a, b)

a.b
(a, b)

- n .
[] , ,
lcm():
#include <stdio.h>
const unsigned n = 4;
const unsigned A[] = { 10, 8, 5, 9 };
unsigned gcd(unsigned a, unsigned b)
{ return (0 == b) ? a : gcd(b, a % b);
}
unsigned lcm(unsigned a[], unsigned n)
{ unsigned b;
if (2 == n)
return(a[0] * a[1]) / (gcd(a[0], a[1]));
else {
b = lcm(a, n - 1);
return(a[n - 1] * b) / (gcd(a[n - 1], b));
}
}

1 -

77

int main(void)
{ printf("%u\n", lcm(A, n));
return 0;
}

lcm.c
:
360

:
1. : [10,15]; [15,10]; [7,8,9]; [3,6,9]; [158,128,256]; [64,28,72,18].
2. , [a1, a2, ..., an] = [[a1, a2, ..., an1], an].
3. , [a,b] = ab / (a,b).
4. ,
.
2; 5; 100; 1000 .

1.2.5.

C, ,
.
.
: n,
, .
, n = 7892 : 7, 8, 9, 2.
.
, :
n%10 n/10. : . ,
:
#include <stdio.h>
unsigned n = 7892;
int main(void)
{ unsigned dig[20], i, k = 0;
while (n > 0) {
dig[k] = n % 10;
n = n / 10;
k++;
}
for (i = k; i > 0; i--) printf("%u ", dig[i-1]);
printf("\n");
return 0;
}

print.c
- . : 7892,
789 2. , n, (!)
n/10 n%10. , ,

1 -

78

.
:
void printN(unsigned n)
{ if (n >= 10) printN(n / 10);
printf("%u ", n % 10);
}

printrec.c
, , n 9, .. n .
.
- . , ,
. -
: n!
, i (
,
):
#include <stdio.h>
const unsigned n = 6;
unsigned i;
unsigned long fact(void)
{ if (1 == i) return 1;
return --i * fact();
}
int main(void) {
i = n + 1;
printf("%u! = %lu \n", n, fact());
return 0;
}

factrec.c
: "" return --i * fact(); :
factrec.c Borland C DOS, Microsoft Visual
C++ Windows.
: n 10k (1 k n). , n = 5 :
10, 100, 1000, 10000, 100000, 100000, 10000, 1000, 100, 10
.
:
1. ( n) :
#include <stdio.h>
const unsigned n = 5;
void printRed(unsigned k, unsigned long result)
{ printf("%lu ", result);
if (k < n) printRed(k + 1, result * 10);
printf("%lu ", result);
}

1 -

79

int main(void) {
printRed(1, 10);
printf("\n");
return 0;
}

print1.c
2. - k :
#include <stdio.h>
const unsigned n = 5;
unsigned k = 0;
void printRed(unsigned long result)
{ k++;
printf("%lu ", result);
if (k < n) printRed(result * 10);
printf("%lu ", result);
}
int main(void) {
printRed(10);
printf("\n");
return 0;
}

print2.c
3. result
, :
#include <stdio.h>
const unsigned n = 5;
unsigned long result = 1;
unsigned k = 0;
void printRed(void)
{ k++;
result *= 10;
printf("%lu ", result);
if (k < n) printRed();
printf("%lu ", result);
result /= 10;
}
int main(void) {
printRed();
printf("\n");
return 0;
}

print3.c
, (
-), .
:

1 -

80

1.
factrec.c Borland C DOS Microsoft Visual C++ Windows.
?
2. -.
Borland C DOS Microsoft Visual C++ Windows?
?
unsigned i = 1;
printf("%u %u", ++i, i);

:
unsigned i = 1;
printf("%u %u", i, ++i);

3. x
-. Borland C DOS Microsoft Visual
C++ Windows? ?
unsigned x, a = 3, b = 5;
x = a+++b;

4.
.

1.3.
, , () .

. ( )
.
, :
, .. ,
52 , 5 ,
( : ).
- ,
9.
- : , . ,
( )
.

1.3.1.
1.22. n- A = {a1, a2, ..., an}.
n-, A, A ,
.
Pn, |Pn|.
, |Pn| = n!
, e {a, b, c} 3 , (.. n-) :

1 -

81
(a, b, c)
(a, c, b)
(b, a, c)
(b, c, a)
(c, a, b)
(c, b, a)

, ,
1 n.
( n-
n ).

-
:
1:
,
n1
n1 . :
/* i */
void permute(i) {
if (i >= n) { /*
*/
printPerm();
} else
for (k = 0; k < n; k++)
if (!used[k]) {
/* k */
used[k] = 1;
/* k */
position[i] = k; /* i k */
permute(i+1);
used[k] = 0;
/* k */
}
}

permute() : , "" . i- , , (i+1)- . used[], : , used[k] == 1, used[k] == 0, (..


""). i == n
, .
, n! n
(n ):
#include <stdio.h>
#define MAXN 100
const unsigned n = 3;
char used[MAXN];
unsigned mp[MAXN];
void print(void)
{ unsigned i;
for (i = 0; i < n; i++) printf("%u ", mp[i] + 1);
printf("\n");
}

1 -

82

void permute(unsigned i)
{ unsigned k;
if (i >= n) { print(); return; }
for (k = 0; k < n; k++) {
if (!used[k]) {
used[k] = 1; mp[i] = k;
permute(i+1); /* if ( )
{ permute(i+1); } */
used[k] = 0;
}
}
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) used[i] = 0;
permute(0);
return 0;
}

permute.c
:
1
1
2
2
3
3

2
3
1
3
1
2

3
2
3
1
2
1

-, if.
, , , , . ( 6) ,
.
: , , : ki i- ,
.

1 i 10
i ki

20

, . ,
,
20, - ,
.
- . ,
(i1, i2, , in) (j1, j2, ,jn) k (1 k < n)
, ip = jp, p = 1, 2, , k1 ik < jk . -,
:
- , -.
: k+1
k, . used[]. , [-1998]:
2:
1) n = 1 : (1).

1 -

83

(p1, p2,, pk ), k (1 k < n) .


(k+1) 1,2, , (k+1)- :

2)

(pk+1,p1,p2,,pk )
(p1, pk+1,p2,,pk )

(p1,p2,,pk , pk+1)
, 2) k , k+1 .
- 2. , .
#include <stdio.h>
#define MAXN 100
const unsigned n = 3;
unsigned a[MAXN];
void print(void)
{ unsigned i;
for (i = 0; i < n; i++) printf("%u ", a[i] + 1);
printf("\n");
}
void permut(unsigned k)
{ unsigned i, swap;
if (k == 0) print();
else {
permut(k - 1);
for (i = 0; i < k - 1; i++) {
swap = a[i]; a[i] = a[k-1]; a[k-1] = swap;
permut(k - 1);
swap = a[i]; a[i] = a[k-1]; a[k-1] = swap;
}
}
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) a[i] = i;
permut(n);
return 0;
}

permswap.c
:
1
2
3
2
1
3

2
1
2
3
3
1

3
3
1
1
2
2

:
1. , n- n!
2. {a,b,c,d}, :
) 1

1 -

84

) 2
.
3. 1 2.
4. , permswap.c 2.
5. .

-
,
( 9) memoization ( 8)
.
, - .
, :
(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1).
0 5. ,
n- 0 n!
1. ( )
() [-1995]:

1) perm[] n, ,
.
2) pos = result = 0, p[] n , p[i] = i+1, i = 0,1, ..., n1.
3) pos < n, , r- p, r i,
i , perm[pos] == p[i].
result .
4) result = result*(n pos) + r.
5) pos++ 3).

1) num .
k = n-1, p[] n- , p[i1] = i, i = 1, 2, ..., n.
2) k 0 :
m = n - k;
perm[k] = num % m;
if (k > 0) num /= m;
k--;

3)

k = 0. k < n :
m = perm[k];
perm[k] = p[m];
if (k < n)
for (i = m+1; i < n; i++) p[i-1] = p[i];
k++;

, :
#include <stdio.h>
#define MAXN 100
const unsigned n = 6;
const unsigned perm[MAXN] = { 5, 3, 6, 4, 2, 1 };
const unsigned long code = 551;

1 -

85

unsigned long codePerm(unsigned n, const unsigned perm[])


{ unsigned p[MAXN], i, pos;
unsigned long r, result;
result = 0;
for (i = 0; i < n; i++) p[i] = i + 1;
for (pos = 0; pos < n; pos++) {
r = 0;
while (perm[pos] != p[r]) r++;
result = result * (n - pos) + r;
for (i = r + 1; i < n; i++) p[i - 1] = p[i];
}
return result;
}
void decodePerm(unsigned long num, unsigned n, unsigned perm[])
{ unsigned long m, k;
unsigned i, p[MAXN];
for (i = 0; i < n; i++) p[i] = i + 1;
k = n;
do {
m = n - k + 1;
perm[k - 1] = num % m;
if (k > 1) num /= m;
} while (--k > 0);
k = 0;
do {
m = perm[k]; perm[k] = p[m];
if (k < n)
for (i = m + 1; i < n; i++) p[i - 1] = p[i];
} while (++k < n);
}
int main(void) {
unsigned i, dperm[MAXN];
printf(" %lu \n", codePerm(n, perm));
printf(" %lu: ", code);
decodePerm(code, n, dperm);
for (i = 0; i < n; i++) printf("%u ", dperm[i]);
printf("\n");
return 0;
}

codeperm.c
:
551
, 551: 5 3 6 4 2 1

:
1. -, : (2,3,1,4),
(5,3,2,4,1), (3,6,4,1,5,2).
2. -, 5
, : 3, 13, 27, 87, 119.

1 -

86

-
(.. A ). A = {1, 1, 2, 3} 4
. .
n-, A. ,
(1, 1, 2,
3), . , , , .
~ s1 ,s2 ...,s , s
P
i
n
i (i = 1,2,,k).
:

~
| Pns1 ,s2 ,...,sn |

k
n!
, n
si (*)

s1! s2!... sk !
i 1

s1 = 2, s2 = 1, s3 = 1 | P42,1,1 |

4!
12 .
2!.1!.1!

:
1. {1,1,2,3}.
2. .
? ,
. ?
3. . .
4. .
5. (*).

1.3.2.
- ,
, , . , , . , , , n , . :
1.
for (a1 = 1; a1 <= k; a1++)
for (a2 = 1; a2 <= k; a2++)
for (a3 = 1; a3 <= k; a3++)
...
for (an = 1; an <= k; an++)
printf(" %u %u %u %u;, a1, a2, a3, , an);

n = 2 k = 3, 2
i 1 3, :
1 1; 1 2; 1 3; 2 1; 2 2; 2 3; 3 1; 3 2; 3 3;

1 -

87

2.
for (a1 = 1; a1 <= k; a1++)
for (a2 = 1; a2 <= k; a2++) if (a2 != a1)
for (a3 = 1; a3 <= k; a3++) if ((a3 != a1) && (a3 != a2))

for (an = 1; an <= k; an++)


if ((an!=a1)&&(an!=a2)&&(an!=a3)&&&&(an!=an-1))
printf( %u %u %u %u;, a1, a2, a3, ,an);

n = 2 k = 3 :
1 2; 1 3; 2 1; 2 3; 3 1; 3 2;
, .

n k- , n
k- . -:
A n .
1.23. n k- k- , A ( ).

Vn k
k
n . .
1.24. n- k-
k- , A.
| V k |
n

n! .
(n k )!

, k = n
.
n k, A, 1 n. , ,
, -. , . , ,
( ).
used[] permute.c :
#include <stdio.h>
#define MAXN 100
const unsigned n = 4;
const unsigned k = 2;
int taken[MAXN];
void print(unsigned i)
{ unsigned l;
printf("( ");
for (l = 0; l <= i - 1; l++) printf("%u ", taken[l] + 1);
printf(")\n");
}
void variate(unsigned i) /* */

1 -

88

{ unsigned j;
/* if (i>=k) return; ( print(i);
* 1,2, , k, k */
if (i >= k) { print(i); return; }
for (j = 0; j < n; j++) {
/* if (allowed(i)) { */
taken[i] = j;
variate(i + 1);
}
}
int main(void) {
variate(0);
return 0;
}

variate.c
:
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4

1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4

)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)

:
1. , .
2. 3- {a,b,c,d,e}:


3. , k- n- nk .
4. , k- n- n!/ (nk)!
5. / .
6. .

-
a1, a2, ..., an. "+" "" ai
ai+1, i = 1,2, , n1 , 0.
, 1 8,
:
1+2+3+4567+8=0
1+2+34+56+78=0
1+23+4+5+678=0

1 -

89
1+23456+7+8=0

: n1
, .. (n1)-, 0 1 (
). (n1)-
, .
, n
, a[] :
#include <stdio.h>
#include <math.h>
/* */
const unsigned n = 8;
/* */
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
/* */
int sum = 0;
void checkSol(void)
{ unsigned i;
int tempSum = 0;
for (i = 0; i < n; i++) tempSum += a[i];
if (tempSum == sum) { /* => */
for (i = 0; i < n; i++)
if (a[i] > 0) printf("+%d ", a[i]);
else printf("%d ", a[i]);
printf(" = %d\n", tempSum);
}
}
void variate(unsigned i)
{ if (i >= n) {
checkSol();
return;
}
a[i] = abs(a[i]); variate(i + 1);
a[i] = -abs(a[i]); variate(i + 1);
}
int main(void) {
variate(0);
return 0;
}

sumzero.c
:
+1
+1
+1
+1
+1
+1
+1
-1
-1
-1

+2
+2
+2
+2
-2
-2
-2
+2
+2
+2

+3
+3
-3
-3
+3
-3
-3
+3
+3
-3

+4
-4
+4
-4
-4
+4
+4
-4
-4
+4

-5
+5
+5
-5
-5
+5
-5
+5
-5
+5

-6
-6
+6
-6
+6
-6
+6
-6
+6
-6

-7
+7
-7
+7
-7
-7
+7
-7
+7
+7

+8
-8
-8
+8
+8
+8
-8
+8
-8
-8

=
=
=
=
=
=
=
=
=
=

0
0
0
0
0
0
0
0
0
0

1 -
-1
-1
-1
-1

-2
-2
-2
-2

+3
+3
-3
-3

+4
-4
+4
-4

+5
-5
-5
+5

+6
-6
+6
+6

-7
+7
-7
+7

-8
+8
+8
-8

90
=
=
=
=

0
0
0
0

:
1. , ,
.
2. . , k- , ..
, 0,
nk ?

1.3.3.
,
. n .
1.25. n k- k- .
1.26. n k- k- , A.
n = 4, k = 2 {a,b,c,d}
{a,b}, {a,c}, {a,d}, {b,c}, {b,d}, {c,d},
: {a,a}, {a,b}, {a,c}, {a,d}, {b,b}, {b,c}, {b,d}, {c,c}, {c,d}, {d,d}.
. - , . , , 1.5.
,
1.1.5., :

n
n.(n 1)...(n k 1)
n!
C kn

,
k (k 1)...1
k!(n k )!
k
:

~
(n k 1)!
C kn
k!(n 1)!

. ,
, .
, ,
.
#include <stdio.h>
#define MAXN 20
/* n k- */
const unsigned n = 5;
const unsigned k = 3;
unsigned mp[MAXN];

1 -

91

void print(unsigned length)


{ unsigned i;
for (i = 0; i < length; i++) printf("%u ", mp[i]);
printf("\n");
}
void comb(unsigned i, unsigned after)
{ unsigned j;
if (i > k) return;
for (j = after + 1; j <= n; j++) {
mp[i - 1] = j;
if (i == k) print(i);
comb(i + 1, j);
}
}
int main(void) {
printf("C(%u,%u): \n", n, k);
comb(1, 0);
return 0;
}

comb.c
:
1
1
1
1
1
1
2
2
2
3

2
2
2
3
3
4
3
3
4
4

3
4
5
4
5
5
4
5
5
5

:
1. , .
2. 3- {a,b,c,d,e}:


3. n
k .
4. , k- n-
n! / (k!(nk)!).
5. , k- n- (n+k1)! / (k!(n1)!). : .
6. / .
7. / .

1 -

92

1.3.4.
-

: n () n ( ).
, 5 7 :
5=5
5=4+1
5=3+2
5=3+1+1
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
, , :
(0) = {}
(n) = {k} + (nk), k = n, n1,,1.
, :
5=3+2
5=2+3
: . , , : n ( ) pos , :
#include <stdio.h>
#define MAXN 100
const unsigned n = 7;
unsigned mp[MAXN + 1];
void print(unsigned length)
{ unsigned i;
for (i = 1; i < length; i++)
printf("%u+", mp[i]);
printf("%u\n", mp[length]);
}
void devNum(unsigned
{
if (0 == n)
print(pos-1);
else {
unsigned k;
for (k = n; k >=
mp[pos] = k;
if (mp[pos] <=
devNum(n-k,
}

n, unsigned pos)

1; k--) {
mp[pos-1])
pos+1);

1 -

93

}
}
int main(void) {
mp[0] = n+1;
devNum(n, 1);
return 0;
}

devnum.c
:
7
6+1
5+2
5+1+1
4+3
4+2+1
4+1+1+1
3+3+1
3+2+2
3+2+1+1
3+1+1+1+1
2+2+2+1
2+2+1+1+1
2+1+1+1+1+1
1+1+1+1+1+1+1

, (
) .
. ,
. , , -, 8.3.6.
:
1. .
2. .

, , ,
. devNum(n-k,cnt+1) devNum(n/k,cnt+1),
k, , n % k == 0.
( for) k > 1, k 1, .. k == 1,
k == 0 ( : 0 1
). :
#include <stdio.h>
#define MAXLN 20 /* M: - log2n ( 2) */
const unsigned n = 50; /* , */
unsigned mp[MAXLN];
void print(unsigned length)
{ unsigned i;
for (i = 1; i < length; i++) printf("%u * ", mp[i]);
printf("%d\n", mp[length]);

1 -

94

}
void devNum(unsigned n, unsigned pos) {
if (1 == n)
print(pos-1);
else {
unsigned k;
for (k = n; k > 1; k--) {
mp[pos] = k;
if (mp[pos] <= mp[pos-1] && n % k == 0)
devNum(n / k, pos+1);
}
}
}
int main(void) {
mp[0] = n + 1;
devNum(n, 1);
return 0;
}

devnum2.c
:
50
25 * 2
10 * 5
5 * 5 * 2

:
1. .
2. .

,
. , 2, 5 10
20 . ( 6 )
:
20
20
20
20

20 = 10
= 10 + 5 +
= 10 + 2 +
= 5 + 5 +
= 5 + 5 +
20 = 2

+
5
2
5
2
+

10
+
+
+
2

2 + 2 + 2
5
2 + 2 + 2 + 2
+ 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2


. , ,
given[gN]. p = 0,1,...,gN-1,
p, n given[p]:
#include <stdio.h>
#define MAX_ADDS 100
/* , */
const unsigned n = 15;
/* */

1 -

95

const unsigned gN = 3;
/* */
const unsigned given[] = { 2, 3, 5 };
unsigned mp[MAX_ADDS];
void print(unsigned length)
{ unsigned i;
for (i = 1; i < length; i++)
printf("%u + ", mp[i]);
printf("%d\n", mp[length]);
}
void devNum(unsigned n, unsigned pos)
{ unsigned k, p;
for (p = gN; p > 0; p--) {
k = given[p - 1];
if (n > k) {
mp[pos] = k;
if (mp[pos] <= mp[pos - 1])
devNum(n - k, pos + 1);
}
else if (n == k) {
mp[pos] = k;
if (mp[pos] <= mp[pos - 1])
print(pos);
}
}
}
int main(void) {
mp[0] = n + 1;
devNum(n, 1);
return 0;
}

devnum3.c
:
5
5
5
5
3
3
3

+
+
+
+
+
+
+

5
5
3
2
3
3
2

+
+
+
+
+
+
+

5
3
3
2
3
3
2

+
+
+
+
+
+

2
2
2
3
2
2

+
+
+
+
+

2
2 + 2
3
2 + 2
2 + 2 + 2

:
1. ? : ? :
?
2. .
3. .
4. .

1 -

96

1.3.5.
, ,
, ..
. , A = {1, 2, 3} :
{1,2,3}
{1,2}, {3}
{1,3}, {2}
{1}, {2,3}
{1}, {2}, {3}

-
- , -.
n n- B(n). :
n

B(n) St (n, k ) ,
k 0

St(n,k) , :

St (n 1, k 1) k .St (n 1, k ), k 2,3,..., n
1, n 0, k 1

St (n, k )
0, k 0
0, n 0
n- k .
.
.
, . ,
.
: M[i] = St(n,i), i =
0,1,...,n. n- .
,
. , , .
1
1
1
1
1

1
3

7
15

1
6

25

1
10

1
1
31
90
65
15
1
.........................................

1.3.5. .
#include <stdio.h>
#define MAXN 100
const unsigned long n = 10;
unsigned long M[MAXN+1];
void stirling(unsigned n)

1 -

97

{ unsigned i, j;
if (0 == n) M[0] = 1;
else M[0] = 0;
for (i = 1; i <= n; i++) {
M[i] = 1;
for (j = i - 1; j >= 1; j--) M[j] = j * M[j] + M[j - 1];
}
}
unsigned long bell(unsigned n)
{ unsigned i;
unsigned long result = 0;
for (i = 0; i <= n; i++) result += M[i];
return result;
}
int main(void) {
stirling(n);
printf("bell(%lu) = %lu\n", n, bell(n));
return 0;
}

bell.c
:
bell(10) = 115975

:
1. .
2. .
3. ,
. 1.1.5.
4. .

1.4.
, .
. ,
, -.
, - :

( )

"" ( ),
- . ,
,
, ,
.
:

1 -
1)
2)
3)
4)
5)

98

n = 100;
sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
sum++;

. ,
, . - , n. 1.4. .

10
100
1000
10000
100000
1000000


0,000001 .
0,0001 .
0,01 .
1,071 .
106,543 .
10663,6 .

1.4. .
1.4. , n ,
100 .
- . 1) 2) , . a. i = 0 i++,
i < n, (
), b, c, d. 4) , j = 0, j < n j++, e, f, g. , 5)
: h.
n:
a + b + n.c + n.d + n.(e + n.f + n.g + n.h) =
= a + b + n.c + n.d + n.e + n.n.f + n.n.g + n.n.h =
= n2.(f + g + h) + n.(c + d + e) + a + b
, a, b, c, d, e, f, g, h . :
i=f+g+h
j=c+d+e
k=a+b
( i j - ).
:
i.n2 + j.n + k
i, j k , .
, .
,
, .
, ,
j.n k , n - .
"" - , .. , - , .. -, .
, 1 A2 n : f = 2.n2 g = 200.n. -

1 -

99

, g - f, n
( n > 100), A2 - 1.
, n,
A2. A2 , A1 .
- - .
:
1. 5n2 7n + 13, 3n2 + 15n + 100
1000n. : 100; 1000; 10000; 1000000?
2. 5n3 5n2 + 5 ?
3
5n 5n2 5? 5n3 5n2 + 5?

1.4.1.
, n. , , . , :
1. n .
n .
2. a b - .
()
- a b: .. log2(max(a,b)). - ,
.
3. ( 5.1.).
:
.

1.4.2.
, -
n . n, .
f : N N. ( ,
N : 0,1,2,...). , N, n
. , log n, N. ""
, .
1.27. O(F(n)) = {f(n) | c (c > 0), n0(c): n > n0 : 0 f(n) c.F(n) }
.. O(F(n)) f, c (c > 0) ,
f(n) c.F(n), n, .. n0 ( c), n > n0. O(F)
, - F.
, :
(F) (F).
1.28. (F(n)) = {f(n) | c (c > 0), n0 (c): n > n0 : f(n) c.F(n) 0}

1 -

100

T.e. (F) f(n), f(n) c.F(n) n > n0. (F)


, - F.
1.29.
(F(n)) = {f(n) | c1 (c1 > 0), c2(c2 > 0), n0(c1,c2): n n0 : 0 c1.F(n) f(n) c2.F(n)}
, (F) = O(F) (F). .. (F)
, , F ( ).
- (
.):
1.30. o(F(n)) = {f(n) | c (c > 0), n0(c): n > n0 : 0 f(n) < c.F(n) }
, o(F) = O(F) \ (F). .. o(F)
, - F ( ).
, 3n2 O(n2) 3n2 O(n3), 3n2 (n3), 3n2 (n2).
1.31. (F(n)) = {f(n) | c (c > 0), n0 (c): n > n0 : 0 c.F(n) < f(n) }
, (F) = (F) \ (F). .. (F)
, - F ( ).

.
- "", , f (F), e .
, . ,

T(n) :
T(n) = T(n1) + O(n)
:
1. , (F) = O(F) (F).
2. , o(F) = O(F) \ (F).
3. , (F) = (F) \ (F).

1.4.3. O(F):
(F) - . - (F), . - (...)
.
O(F):

: f (f)
: f (g), g (h) f (h)
: f (g) g O(f)
:
k > 0, k.F(F).

1 -

101

n, - , -:
nr(ns), 0 r s.
- ( max):
f + g O(max(f,g)),
:
f(g) f+g (g)
:
O(c1f+c2g) O(max(f,g)), c1,c2 > 0

f(n) d -, f(nd).
:
f(F) g(G) f.g(F.G)

( ):
, f O(g),
n0 c , n (n > n0)
f(n) c.g(n).
(, ):

f ( n)
R f (n) O( g (n)), g (n) O( f (n))
g ( n)
f ( n)
lim
0 f (n) O( g (n)), g (n) O( f (n))
n g ( n)
f ( n)
lim
f (n) O( g (n)), g (n) O( f (n))
n g ( n)
lim

().
: log n
:

lim

log n
n

lim

n . ,
1/ n

1/ 2 n

lim

2
n

, log n O( n ),

10n O(n),
10n O(n2),
10n O(n4)
10n O(3n4 10n2 + 7)
10n+3 O(n)
4n2 5n + 2 O(n2)
4n3 + 5n2 +5 O(n3)
n O(n)
log n ( n )

n O(log n).

1 -

102


2n O(1)
4n2 5n + 2 O(n)
5n + 1 O( n )

n 3 O(n)
:
1. , 5n3 5n2 + 5 O(n3).
2. , n O(n).
3. - O(F).
4. - O(F).

5. f(n) g(n), lim f n .


n

g n

1.4.4. (F):
, , ,
(n). , (F) = O(F) (F).
(F):

: f (f)
: f (g), g (h) f (h)
: f (g) g O(f)
:
k > 0, k.F (F).
f(n) d -, f (nd).

( ):
, f (g),
n0 c , n (n > n0)
f(n) c.g(n).
(, ):

f ( n)
R f (n) ( g (n)), g (n) ( f (n))
g ( n)
f ( n)
lim
0 f (n) ( g (n)), g (n) ( f (n))
n g ( n)
f (n)
lim
f (n) ( g (n)), g (n) ( f (n))
n g ( n)
().
lim

1 -

103

10n (n)
10n+3 (1)
4n2 5n + 2 (n2)
4n2 5n + 2 (n)
4n3 + 5n2 +5 (n3)
4n3 + 5n2 +5 (n2)
4n3 + 5n2 +5 (7n 10)
n ( n )

n (log n)
:
4n2 5n + 2 (n3)
n (n)
log n ( n )
:
1. , 5n3 5n2 + 5 (n3).
2. , n (n0,48).
3. - (F).
4. - (F).

1.4.5. (F):
(F):

: f (f)

: f (g), g (h) f (h)

: f (g) g (f)

:
k > 0, k.F (F).

- :
f + g max((f(n)), (g(n))),
:
f (g) f+g (g)
:
(c1f(n) + c2g(n)) max((f(n)), (g(n))), c1,c2 > 0

f(n) d, f (nd).

1.32. , ,
, .
R = (...), (f,g) R , f (g). (...) 1.3.2. , R
.
( ):

1 -

104

, f (g),
n0 c1 c2 , n
(n > n0) c1.g(n) f(n) c2.g(n).
1:
n2/2 3n. ,
(n2). c1, c2 n0, c1.n2 n2/2 3n c2.n2 (n > n0).
n2 ( n > 0) : c1 1/2 3/n c2.
c1 = 0, c2 = 1/2 n0 = 5. .
, c1, c2 n0 . ,
c1 = 1/20, c2 = 1 n0 = 100.
.
2:
2n3. , (n2). , , c2 ,
6n3 c2.n2. n2 ( n > 0) , 6n c2, : n c2/6. , n -
. n0, n, n > n0 n c2/6: ,
.
:

f ( n)
R f (n) ( g (n)), g (n) ( f (n))
g ( n)
f ( n)
lim
0 f (n) O( g (n)), f (n) ( g (n)), .. f (n) o( g (n))
n g ( n)
f (n)
lim
f (n) ( g (n)), f (n) ( g (n)), .. f (n) ( g (n))
n g ( n)
.
lim

:
10n (n)
4n2 5n + 2 (n2)
4n2 5n + 2 (6n2 n + 1)
log10 n (log2 n)
:
10n (1)
10n (n2)
4n2 5n + 2 (n3)
4n2 5n + 2 (n + 1)
1.33. (1) , (log n) , (n)
, (n2) , (cn) . f e ,
(f) .

1 -

105

:
1. , 5n3 5n2 + 5 (n3).
2. , n (n0,48).
3. - (F).
4. - (F).
5. , R = (...) ( (f,g) R
, f (g)) .
6. :

) 4n3 + 5n2 +5 (n4)


) log2n ( n )
) 4n3 + 5n2 +5 (7n4 10)
) n ( n )
) log2n ( n )
) 10n+3 O(n)
) 10n O(3n4 10n2 + 7)
) 5n + 1 O( n )
7. :

) (F) = O(F) ( F)
) (F) = (F) \ (F)
) o(F) = O(F) \ (F)
) O(c1f+c2g) = O(max(f,g))
) f (g) g (f)
) f (g) g (f)
) f (g) g O(f)
8. :

) lim f (n) R f (n) O( g (n)), g (n) O( f (n))


n g ( n)
) lim f (n) 0 f (n) O( g (n)), g (n) O( f (n))
n g ( n)
) lim f (n) f (n) O( g (n)), g (n) O( f (n))
n g ( n)
) lim f (n) R f (n) ( g (n))
n g ( n )
) lim f (n) 0 f (n) ( g (n)), f (n) ( g (n))
n g ( n)

1.4.6.
- , . 1.4.6.
,
: , .. a b
: a < b, a = b a > b. , n n1+cos n

1 -

106

.
.

f O(g)
f (g)
f (g)
f o(g)
f (g)


ab
ab
a=b
a<b
a>b

1.4.6. .
:
1. .
2. f(n) g(n) ,
, f g ?

1.4.7.
- : c, log
n, n, n log n, n2, n3, nk , 2n, n!, nn. - .
- , 1.4.7.,
n.

5
log n
n
n log n
n2
n3
2n
n!
nn

n=1

n=2
5
0
1
0
1
1
2
1
1

n = 10
5
1
2
2
4
8
4
2
4

5
3,32
10
33,2
100
1000
1024
3628800
1010

n = 100
5
6,64
100
664
10000
106
1030
10157
10200

n = 1000
5
9,96
1000
9966
106
109
10300
102567
103000

1.4.7. - .
1.4.7. , :

- :
nk (bn), b > 1, k 0, n .

- :
logb n(nk ), b > 1, k > 0, n .
:
1. , n! - cn, c > 0.
2. cn, c > 0 -
( 1.4.7.).

1 -

107

1.4.8.
,
. T()
, . ,
, T(n), ,
n. O(...).
(...) - (...).

-
, .. O(1).
.
. ,
, .
, , .
,
. (,
.), , ,
.
.
,
n.
.

-
. , s1 F1 s2
F2, :
T(s1) O(F1), T(s2) O(F2) T(s1; s2) O(max(F1, F2))
:
f1+ f2 (max(f1, f2))

-

, ..
T(s1) O(F1), T(s2) O(F2) T(s 1{s 2}) O(F1.F2))
:
f1.f2 O(f1.f2)

- if-
if (p)
s1;
else
s2;

p, s1 s2 O(P), O(F1), O(F2),


max(O(P), O(F1), O(F2)), .. - P, F1 F2.

1 -

108

, p , ..
, .
T(p) O(P), T(s1) O(F1) , T(s2) O(F2) T(if (p) s1; else s2) max(O(P), O(F1), O(F2))
. , p .
if- p; s1 (,
.).
max(O(P),O(F1)). , p
max(O(P),O(F2)).
, if-, -
. :
T(if (p) s1; else s2) max(max(O(P),O(F1)), max(O(P),O(F2))) = max(O(P), O(F1), O(F2))
switch .

-
:
fact = 1;
for (i = 1; i <= n; i++)
fact *= i;

, c, n.
for (n). (c.n), .. (n).
( O(1)), ,
, : (1+n). O(n).

-
sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
sum++;


. - f n.O(g), g
. g O(n), f O(n.n), .. f O(n2). -
sum 0, sum++ .
. sum
n.
sum = 0;
for (i = 0; i < n-1; i++)
for (j = i+1; j < n; j++)
sum++;

, i=0, n1
. , i=1, n2 , n3
.., , i=n2, .
1, n1 1. sum++ n.n 1 , ..

O(n2). , sum++
(1).

1 -

109

-
1.
sum = 0;
for (i = 0; i < n*n; i++)
sum++;

O(n2). (?)
2.
sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (i == j)
for (k = 0; k < n; k++)
sum++;

if n2 , n i == j
. - ,
O(n2). , O(n3) , -.
(n2).
3.
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (i == j)
break;

, O(n2), -?
, , ,
!
4.
sum = 0;
for (i = 1; i <= n; i++)
for (j = 1; j <= i*i; j++)
sum++;

n . :
n

i
i 1

n.n 12n 1
6

, O(n3). ,
O(n), O(n2),
i n. i == n i*i == n2 O(n3).
5.
sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++)
for (k = 0; k < j*j; k++)
sum++;

1 -

110

,
- .
-, (...):
O(n3).
O(n4) , i = n,
k j2 = i4 = n4. ( ?)

-
:
for(sum = 0, h = 1; h < n; h *= 2)
sum++;

h 1,2,4,...,2k ,... n. sum++ log2 n


O(log2 n). , ,
. - ,
/.
, () . ,
- - ( 4.3.).
- O(log2 n), O(log n). ,
. ,
, (4) 1.1.1. , , n- .
c (c > 0, c 1) , , log2 x = logc x / logc 2, logc
2 . O(log2 n) O(logc n).

-
.
T(n) = f(T(n1)). , , .

.
-
:
unsigned fact(unsigned n)
{ if (n < 2)
return 1;
return n*fact(n-1);
}

for, O(n).
-
. ,
1.2.2., :
unsigned fib(unsigned n)
{
if (n < 2)
return 1;
return fib(n-1) + fib(n-2);
}

1 -

111

n = 0 n = 1 : . ,
. , :
T(0) = T(1) = O(1)
T(n) = T(n1) + T(n2) + O(1), n 2
:
f0 = f1 = 1
fn = fn1 + fn2
, T(n) fn. : 3

n 1

fn 2n, n 1 ( .). , T(n) -

.
, ,
, O(n):
unsigned long f[MAX] = {0,0,0,...};
unsigned long fib(unsigned n)
{
if (0 == f[n])
if (n < 2)
f[n] = 1;
else
f[n] = fib(n-1) + fib(n-2);
return f[n];
}

- (memoization) 8.
:
1. , if-then-else
T(p) O(P), T(s1) O(F1) , T(s2) O(F2) T(if (p) s1; else s2) max(O(P), O(F1), O(F2))
switch.
2. , 1 - (n2).
3. , 3 - (n2).
4. (...) 5.
5. O(...) (...) 1.4.8.?
6. , : 3

7. (...) :
for (i = 0; i < 2*n; i++)
for (j = 0; j < 2*n; j++)
if (i<j) for (k = 0; k < 2*n; k++) break;

8. (...) :
unsigned sum = 0;
for (i = 0; i < n; i++)
for (j = i+1; j < i*i; j++) sum++;

9. (...) :

n 1

fn 2n, n 1.

1 -

112

for (i = 0; i < n; i++)


for (j = 0; j < n; j++)
if (i==j)
for (k = 0; k < n; k++) break;

10. (...) :
unsigned sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++) sum++;

11. (...) trib():


unsigned trib(unsigned n)
{
if (n < 3)
return 1;
if ((n % 2) == 1)
return trib(n-1) + trib(n-2) + trib(n-3);
else
return trib(n / 3) + trib(n / 2);
}

12. (...) streep():


unsigned fib(unsigned n)
{
if (n < 2)
return 1;
return fib(n-1) + fib(n-2);
}
void streep(unsigned n) {
fib(fib(n));
}

13. (...) :
int n = 10;
int i;
for (i = 0; i < n; (n = i)++);

1.4.9.
.
, -
, .
. ...

-
:
a0T(n) + a1T(n1) + ... + ak T(nk) = 0

(1)

T(n) . , T(n), .. .
. T(n) = xn, :

1 -

113

a0xn + a1xn1 + ... + ak xnk = 0

(2)

, , x = 0, . ,
xnk ( x 0) k
:
a0xk + a1xk1 + ... + ak = 0
(3)
k. ,
k ( , .. ). i (1 i k). :
0 = a0xk + a1xk1 + ...+ ak = 0(x 1)(x 2)...(x k )

(4)

(4) x , , i (1 i k) (3), (2). T(n) = xn, ,


in (1).
(1) . , i
, in (1), ..
in.
(1) :
T(n) = c1 1n + c2 2n + ... + ck k n
(5)
nk

c1, c2, ..., cn ,


. - .
:
, :
T(n) = T(n1) + T(n2)
(4) :
x2 = x + 1
a :

1, 2

1 5
2

(5), ..:
T(n) = c1 1n + c2 2n

(6)

c1 c2 T(0) = 0 T(1) = 1,
(6), :
T(0) = 0 = c1 + c2
T(1) = 1 = c1 1 + c2 2
:

1
1
, c2
5
5
(6) T(n).
.
n
n
1 1 5 1 5

T ( n)
5 2 2

c1

1 -

114

, n. . , n
.

-
(4) -
(5). , n n. ,
, ..
. , n n
n2 n. , p- ns n, 0 s p.
i (1 i k) , .
(3) 1, 2, ..., l, 1 l k. qj j, 1 j l.
(1) :
l

q j 1

T (n) c j ,r 1n r jn

(7)

j 1 r 0

cj,r+1 , , -, .
:

n 0,1
3

T (n) 5
n2
4T (n 1) 5T (n 2) 2T (n 3) n 3

:
x3 = 4x2 5x + 2
, :
x3 4x2 + 5x 2 = 0
, :
T(n) (7):

x1 = x2 = 1, x3 = 2

T(n) = c1,1.1n + c1,2.n.1n + c2,1.2n

(8)

c1,1, c1,2, c2,1 n = 0, 1 2.


:
T(0) = 3 = c1,1
+ c2,1
T(1) = 3 = c1,1 + c1,2 + 2c2,1
T(2) = 5 = c1,1 + 2c1,2 + 4c2,1
:
c1,1 = 1, c1,2 = 2, c2,1 = 2
(8) :
T(n) = 1 2n + 2n+1

-
.
:
: :

1 -

115

float P(unsigned i, unsigned j)


{ if (0 == i)
return 1.0;
else if (0 == j)
return 0.0;
else
return p * P(i - 1, j) + (1 p) * P(i, j - 1);
}
P(n,n) n.

:
- i
j, i = j = n.
, P() P(i,j),
:
P(0,j) = 1, j = 1,2,, n
P(i,0) = 0, i = 1,2,, n
P(i,j) = p.P(i1, j) + (1p).P(i, j1) , i > 0 , j > 0
, .
, i j. , k = i + j,
:
T(1) = c
T(k) = 2T(k1) + d, k > 1
, P(i,j),
P().
c d, . -
, .

, . :
T(k) = 2T(k1) + d
T(k+1) = 2T(k) + d
, , :
T(k+1) T(k) = 2.[T(k) T(k1)]
:
T(k+1) 3T(k) + 2T(k1) = 0
:
x2 3x + 2 = 0

(x1)(x2) = 0,
, 1 = 2 2 = 1. ..
T(k) :
T(k) = c1 1k + c2 2k
:
T(k) = c12k + c2

1 -

116

c1 c2 , T(1) T(2). :
T(1) = c
= 2c1 + c2
T(2) = 2c + d = 4c1 + c2
:
c1 = (c + d) / 2
c2 = d
c1 0 , T(k) (2k ). (?) k = i +
j, (2i+j). ,
P(n,n), .. i = j = n. (22n)
: (4n).
:
:
a0T(n) + a1T(n1) + ... ak T(nk) = b1n p1(n) + b2n p2(n) + ... + bsn ps (n)

(9)

b1, b2, ..., bs , p1(n), p2(n), .., ps (n) n. d1, d2, ..., ds.
(9) :
(a0xk + a1xk1 + ... + ak ) (xb1)d1+1(xb2)d2+1... (xbs )ds+1 = 0

(10)

(10) - , .
:
:

0
T ( n)
n
2T (n 1) n 2

n0
n 1

:
T(n) 2T(n1) = n + 2n,

(11)

b1 = 1, b2 = 2, p1(n) = n, p2(n) = 1, : d1 = 1, d2 = 0.
:
(x2)(x1)2(x2) = 0.
x1 = x2 = 1, x3 = x4 = 2. T(n):
T(n) = c1,1.1n + c1,2.n.1n + c2,1.2n + c2,2.n.2n

(12)

, .
T(n) . :
T(0) = 0 = c1,1
+ c2,1
T(1) = 3 = c1,1 + c1,2 + 2c2,1 + 2c2,2
T(2) = 12 = c1,1 + 2c1,2 + 4c2,1 + 8c 2,2
T(3) = 35 = c1,1 + 3c1,2 + 8c2,1 + 24c 2,2
c1,1 = 2, c1,2 = 1, c2,1 = 2 c2,2 = 1. (12)
T(n) :
T(n) = 2 n + 2n+1 + n.2n

(13)

1 -

117

, (
). (12)
(11), :
c2,22n c1,2n + (2c1,2 c1,1) = 2n + n

(14)

2 , c2,2 = 1.
, n c1,2 = 1. , c1,2, c1,1 = 2. c1,2
, , .
,
. , ,
T(n), . , (13) T(n),
, T(n) (n2n). - .
, (12) , T(n) O(n2n). , ,
. (...),
, c2,2 - n2n
0. , (14) , c2,2 = 1, .. c2,2 0 ,
T(n) (n2n). , c2,2 0, c2,1
- 2n ..
:
1)

. , c2,2 0.

2)

. T(0) = 0, , T(n) (n2n)


T(0). , ,
(9). , c2,1
(13)
T(0). c2,1 - ,
T(0) .

:
, :
) T(1) = 1, T(n) = 4T(n1) 2n, n 2
) T(1) = 0, T(n) = 2T(n1) + n + 2n, n 2
) T(0) = 1, T(n) = 2T(n1) + n, n 1
) T(1) = 1, T(n) = 2T(n1) + 3n, n 2
) T(1) = 2, T(2) = 3, T(n) = 2T(n1) T(n2), n 3

1.4.10.
-
:
unsigned sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++)
sum++;

- , . : () -

1 -

118

. ,
. ? ,
, .
sum++. ,
sum sum++.

-
- -
- . -
, -
. O(...),
(...): - . , -
. - .
- .
:
void addOne(char c[], unsigned m)
{ int i;
for (i = 0; 1 != c[i] && i < m; i++)
c[i] = 1 - c[i];
}

m , ,
, - 0.
, . 0. ? , - m (.. ),
.
O(m) (m). , addOne() n
, n = 2m1. ? , O(n.m), .. O(n.log2 n). , , .
, [0; 2m1]
. .
() , 0,
. 0 ( 1
) .. - 1 , .. - , - .
, 2n1.
, , , n
(n), - .

-
( 7) :
T(n) = a.T(n/b) + c.nk
1. T(n) = a.T(n/b) + c.nk , n > n0, a 1, b >
1, k 0, c > 0, n0 1 a, b, k, c, n0 . :

1 -

119

( n k )
a bk

k
T (n) (n log n) a b k
(n logb a ) a b k

1:
:
T(1) = 1
T(n) = 3T(n/2) + n, n 2
1, : a = 3, b = 2, c = 1, k = 1. : 3 = a > bk = 2.
(nlog 3).
2:
:
T(1) = d
T(n) = 4T(n/2) + n2, n 2
1, : a = 4, b = 2, c = 1, k = 2. : 4 = a = bk = 22.
(n2.log2 n). ,
d.
3:
:
T(1) = d
T(n) = 2T([ n ]) + log2 n, n 2
m = log2 n :
T(2m) = 2T(2m/2) + m
S(m) = T(2m):
S(m) = 2S(m/2) + m
1: a = 2, b = 2, c = 1, k = 1. : 2 = a = bk = 21.
(m.log2 m). :
T(n) = T(2m) = S(m) = (m.log2 m)= (log2 n.log2(log2 n))
1 - 2:
2. T(n) = a.T(n/b) + f(n), n > n0, a 1, b >
1, n0 1 a,b,n0 . :
1) f(n) O( n logb a ), > 0, T(n) ( n logb a ).
2) f(n) ( n logb a ), > 0, T(n) ( n logb a log 2 n ).
3) f(n) ( n logb a ), > 0, a.f(n/b) c.f(n), c < 1 n,
T(n) (f(n)).
:
, :
log 4
) T(1) = 2, T(n) = 4T(n/3) + n 3 , n 2.

1 -

120

) T(1) = 0 T(2n+1) = T(2n) = T(n) + log2 n, n 2.


) T(1) = 4 T(n) = 2T([ n ]) + log2 n, n 2.

1.4.11.

, . , n.
. , , ,
: , ,
n. ,
, [0,65535], :
(200000n) (2n2). ,
- . , .
n = 100000 > 65535. ,
-.
- .
, ( 3.1.6.) (n.log2 n), ( 3.1.2.) (n2).
n -, 10-20 . ,

. - ,
, .
, .
:
1. : 5n2 7n + 13, 3n2 + 15n + 100
1000n. n, -
.
2. , ?

1.5.
1.5.1.
1.1.
A = {1,2,4,5,7} B = {2,3,4,5,6}. :
AB, AB, A\B, B\A. ( 1.1.1.)
1.2.
A B , AB = A. B? ( 1.1.1.)
1.3.
A B : AB = (AB) \ (AB).
A = {1,2,4,5,7} B = {2,3,4,5,6}. ( 1.1.1.)

1 -

121

1.4.
, A B = B A.
: AB, AB, A\B, B\A, AB? ( 1.1.1.)
1.5.
, , (
1.1.1.).
1.6.
m n, (m,n) : (7,3), (7,3), (7,3),
(7,3), (3, 7), (3,7), (3,7), (3,7). ( 1.1.1.)
1.7.
m n (m 0) n = q.m + r, 0 r < m, (q, r ). ( 1.1.1.)
1.8.
.
? ( 1.1.1.)
1.9.
. ( 1.1.1.)
1.10.
(1), (2) (3) 1.1.1. .
1.11.
, (1), (2) (3)
1.1.1.
1.12.
(1), (2) (3) 1.1.1. ,
:

i 1..n

i n..m

ai a n

,1nm

i 1..m

1.13.
, 1.13.
1.14.
(1), (2) (3) ,
.
1.15.
x y (xR, yN).
1.16.
- .
1.17.
unsigned a[MAX][MAX].
void fillMatrix(unsigned a[][MAX], unsigned n),

a[][] :

1 -

122
0
1
2
3
4

20
0
5
6
7

19
18
0
8
9

17
16
15
0
10

14
13
12
11
0

1.18.
unsigned a[MAX][MAX]. , , n = 5 :
1
2
3
4
5

16
17
18
19
6

15
24
25
20
7

14
23
22
21
8

13
12
11
10
9

1.19.
, P
[1+log10(P)]. ( 1.1.2.)
1.20.
(x)
, -? ( 1.1.3.)
1.21.
. ( 1.1.3.)
1.22.
. ( 1.1.3.)
1.23.
,
. (p1)!, ,
p? ( 1.1.3.)
1.24.
, , p , ,
[2, p ]. ( 1.1.3.)
1.25.
( (
1.1.3.) : 3) k = i2,
i .
. .
1.26.
. ( 1.1.3.)
1.27.
,
4 . ( 1.1.3.)
1.28.
1.1.3. .

1 -

123

1.29.
1.1.3. ,
.
1.30.
1.1.3. , n!
1.31.
n , -. ( 1.1.4.)
1.32.
n , -. . ( 1.1.4.)
1.33.
2n1 , n ? ( 1.1.4.)
1.34.
, ( 1 ) 2. , 6 : 1/1 + 1/2 + 1/3 + 1/6 = 2 (
1.1.4.).
1.35.
, ,
( 1 ) 2. ? ( 1.1.4.)
1.36.
(1), (2) (3) 1.1.5.,
. , (1) :

n
n!
n!
C 0n

1
0
0
!
(
n

0
)!
0
! n!

n
n!
n!
C nn

1
n!(n n)! n!0!
n
1.37.
(1), (2) (3) 1.1.5.
1.38.
1.1.5. 1 (pascalt.c) C k
n
lastLine[] n+1 , - n,
. : ,
, 1 i, 1 k,
- . , k
n, (2) C n k , C k .
n

1.39.
0 1? (
1.1.6.)

1.40.
17 17 : 2; 8; 16. ( 1.1.6.)

1 -

124

1.41.
17 17 2; 8; 16. ( 1.1.6.)
1.42.
,
: 111, 110100, 1110100101, 10010101, 10101010101 10111110101.
( 1.1.6.)
1.43.
,
: 11, 11001, 1010101, 111111, 1010101000, 10101101000 11010111000.
( 1.1.6.)
1.44.
? ( 1.1.6.)
1.45.
17 17 . ( 1.1.6.)
1.46.
157 : 3;5;7;14. ( 1.1.6.)
1.47.
0,321 : 3;5;7;14. ( 1.1.6.)
1.48.
157,321 : 3;5;7;14. ( 1.1.6.)
1.49.
1.1.6.
p- .
1.50.
1.1.6. p- .
1.51.
126(8); 10101(2); 3F2B(16); 3CB(14). ( 1.1.6.)
1.52.
0,233(8); 0,01(2); 0,34(16); 0,2A(14). ( 1.1.6.)
1.53.
126,233(8); 10101,01(2); 3F2B,34(16); 3CB,2A(14).
( 1.1.6.)
1.54.
1.1.6. p-
.
1.55.
: 10; 19; 159; 763; 1991; 1979; 1997; 2002.
( 1.1.7.)
1.56.
: 0; 10; 0,28; 3,14; 1/7. ( 1.1.7.)

1 -

125

1.57.
1.1.7.
.
1.58.
: DCLXXXIV, DCCLXIV, LX,
LXX, LXXX, XL, XXL, XXXL ( 1.1.7.).
1.59.
1.1.7. o .
1.60.
, . 1.1.7.
1.61.
, ( 1.2.2.).
1.62.

n- : . ( 1.2.2.)
1.63.
: (10,5); (5,10); (15,25); (25,15); (7,8,9); (3,6,9); (158,128,256);
(64,28,72,18) ( 1.2.3.).
1.64.
.
10/15 2/3. ( 1.2.3.)
1.65.
, (a1, a2, ..., an) = ((a1, a2, ..., an1), an). ( 1.2.3.)
1.66.
. ( 1.2.3.)
1.67.
, (a, b) = (b, a % b). ( 1.2.3.)
1.68.
1.2.3.,
a b, x y (x, yZ), (a,b) = ax + by?
1.69.
, . 2; 5; 100; 1000 . ( 1.2.3.)
1.70.
a, b c (c > a > b, c a + b 1, a, b c ) - , . d ,
d 0 < d a.
, / .
( 1.2.3.)

1 -

126

1.71.
: [10,15]; [15,10]; [7,8,9]; [3,6,9]; [158,128,256]; [64,28,72,18]. ( 1.2.4.)
1.72.
, [a1, a2, ..., an] = [[a1, a2, ..., an1], an]. ( 1.2.4.)
1.73.
, [a,b] = ab / (a,b). ( 1.2.4.)
1.74.
, . 2; 5; 100; 1000 . ( 1.2.4.)
1.75.

factrec.c Borland C DOS Microsoft Visual C++ Windows.
? ( 1.2.5.)
1.76.
-. Borland C DOS Microsoft Visual C++ Windows? ?
unsigned i = 1;
printf("%u %u", ++i, i);

:
unsigned i = 1;
printf("%u %u", i, ++i);

1.77.
x -. Borland C DOS Microsoft Visual C++
Windows? ?
unsigned x, a = 3, b = 5;
x = a+++b;

1.78.

.
1.79.
, n- n! ( 1.3.1.)
1.80.
{a,b,c,d}, :
) 1 1.3.1.
) 2 1.3.1.
.
1.81.
1 2 1.3.1.
1.82.
, permswap.c 2 1.3.1.

1 -

127

1.83.
. ( 1.3.1.)
1.84.
( 1.3.1.),
: (2,3,1,4), (5,3,2,4,1), (3,6,4,1,5,2).
1.85.
( 1.3.1.),
5 , : 3, 13, 27, 87, 119.
1.86.
{1,1,2,3}. ( 1.3.1.)
1.87.
.
? , . ? ( 1.3.1.)
1.88.

. . ( 1.3.1.)
1.89.
. (
1.3.1.)
1.90.
(*) 1.3.1.
1.91.
, .
1.92.
3- {a,b,c,d,e}:


( 1.3.2.)
1.93.
, k- n-
nk . ( 1.3.2.)
1.94.
, k- n- n!/ (nk)! ( 1.3.2.)
1.95.
/ . (
1.3.2.)
1.96.
.
( 1.3.2.)
1.97.
" " 1.3.2., ,
.

1 -

128

1.98.

" " 1.3.2. , k- ,
.. , 0,
nk ?
1.99.
1.3.3. , .
1.100.
3- {a,b,c,d,e}:


( 1.3.3.)
1.101.
n
k . ( 1.3.3.)
1.102.
, k- n- n! / (k!(nk)!). ( 1.3.3.)
1.103.
, k- n- (n+k1)! / (k!(n1)!). : . ( 1.3.3.)
1.104.
/ .
( 1.3.3.)
1.105.
.
( 1.3.3.)
1.106.
( ,
, ) . ( 1.3.4.)
1.107.

( , , ) ( 1.3.4.).
1.108.
1.3.4. ? : ?
: ?
1.109.

. ( 1.3.4.)
1.110.
. ( 1.3.5.)
1.111.
.
( 1.3.5.)

1 -

129

1.112.
, . 1.1.5. ( 1.3.5.)
1.113.
( 1.3.5.).
1.114.
5n2 7n + 13, 3n2 + 15n + 100 1000n.
: 100; 1000; 10000; 1000000? (
1.4.).
1.115.
5n3 5n2 + 5 ? 5n3 5n2 5?
3
5n 5n2 + 5? ( 1.4.)
1.116.
, (F) = O(F) (F). ( 1.4.2.)
1.117.
, o(F) = O(F) \ (F). ( 1.4.2.)
1.118.
, (F) = (F) \ (F). ( 1.4.2.)
1.119.
O(f), 5n3 5n2 + 5 O(n3). ( 1.4.3.)
1.120.
,

n O(n). ( 1.4.3.)

1.121.
1.4.3. O(F).
1.122.
1.4.3. O(F).
1.123.

f(n) g(n), lim f n .


n

g n

( 1.4.3.)
1.124.
(F), 5n3 5n2 + 5 (n3). ( 1.4.4.)
1.125.
,

n (n

0,48

). ( 1.4.4.)

1.126.
1.4.4. (F).
1.127.
1.4.4. (F).
1.128.
(F), 5n3 5n2 + 5 (n3). ( 1.4.5.)

1 -
1.129.
,

n (n

130

0,48

). ( 1.4.5.)

1.130.
1.4.5. (F).
1.131.
1.4.5. (F).
1.132.
, R = (...) ( (f,g) R
, f (g)) . ( 1.4.5.)
1.133.
:
) 4n3 + 5n2 +5 (n4)
) log2n ( n )
) 4n3 + 5n2 +5 (7n4 10)
) n ( n )
) log2n ( n )
) 10n+3 O(n)
) 10n O(3n4 10n2 + 7)
) 5n + 1 O( n )
( 1.4.2-1.4.5.)
1.134.
:
) (F) = O(F) ( F)
) (F) = (F) \ (F)
) o(F) = O(F) \ (F)
) O(c1f(n)+c2g(n)) = max(O(f(n)), O(g(n)))
) f (g) g (f)
) f (g) g (f)
) f (g) g O(f)
( 1.4.2-1.4.5.)
1.135.
:
) lim f (n) R f (n) O( g (n)), g (n) O( f (n))
n

g ( n)
) lim f (n) 0 f (n) O( g (n)), g (n) O( f (n))
n g ( n)
) lim f (n) f (n) O( g (n)), g (n) O( f (n))
n g ( n)
) lim f (n) R f (n) ( g (n))
n g ( n )
) lim f (n) 0 f (n) ( g (n)), f (n) ( g (n))
n g ( n)
( 1.4.2-1.4.5.)

1 -

131

1.136.
. ( 1.4.6.)
1.137.
f(n) g(n) ,
, f g ? ( 1.4.6.)
1.138.
, n! - cn, c > 0. ( 1.4.7.)
1.139.
cn, c > 0 -
( 1.4.7.).
1.140.
, if-then-else
T(p) O(P), T(s1) O(F1) , T(s2) O(F2) T(if (p) s1; else s2) max(O(P), O(F1), O(F2))
switch. ( 1.4.8.)
1.141.
, 1 1.4.8. (n2).
1.142.
, 3 1.4.8. (n2).
1.143.
(...) 5
1.4.8.
1.144.
O(...) (...) 1.4.8.?
1.145.
, : 3

( 1.4.8.)
1.146.
(...) :
for (i = 0; i < 2*n; i++)
for (j = 0; j < 2*n; j++)
if (i<j) for (k = 0; k < 2*n; k++) break;

( 1.4.8.)
1.147.
(...) :
unsigned sum = 0;
for (i = 0; i < n; i++)
for (j = i+1; j < i*i; j++) sum++;

( 1.4.8.)
1.148.
(...) :
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)

n 1

fn 2n, n 1.

1 -
if (i==j)
for (k = 0; k < n; k++) break;

( 1.4.8.)
1.149.
(...) :
unsigned sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < i*i; j++) sum++;

( 1.4.8.)
1.150.
(...) trib(n):
unsigned trib(unsigned n)
{
if (n < 3)
return 1;
if ((n % 2) == 1)
return trib(n-1) + trib(n-2) + trib(n-3);
else
return trib(n / 3) + trib(n / 2);
}

( 1.4.8.)
1.151.
(...) streep(n):
unsigned fib(unsigned n)
{
if (n < 2)
return 1;
return fib(n-1) + fib(n-2);
}
void streep(unsigned n) {
fib(fib(n));
}

( 1.4.8.)
1.152.
(...) :
int n = 10;
for (int i = 0; i<n; (n=i)++);

( 1.4.8.)
1.153.
, :
) T(1) = 1, T(n) = 4T(n1) 2n, n 2
) T(1) = 0, T(n) = 2T(n1) + n + 2n, n 2
) T(0) = 1, T(n) = 2T(n1) + n, n 1
) T(1) = 1, T(n) = 2T(n1) + 3n, n 2
) T(1) = 2, T(2) = 3, T(n) = 2T(n1) T(n2), n 3
( 1.4.9.)
1.154.
, :

132

1 -

133
log 4

) T(1) = 2, T(n) = 4T(n/3) + n 3 , n 2.


) T(1) = 0 T(2n+1) = T(2n) = T(n) + log2 n, n 2.
) T(1) = 4 T(n) = 2T([ n ]) + log2 n, n 2.
( 1.4.10.)
1.155.
: 5n2 7n + 13, 3n2 + 15n + 100 1000n.
n, -
. ( 1.4.11.)
1.156.
, ? ( 1.4.11.)

1.5.2.
- , ,
, -,
(, ). , ,
.
1.157.
, , .
: ( ),
. 9 ,
9.9! = 3265920, - 9- .
1.158.
1.34. p q , p = q + 2.
, . 4 {3,5}
{5,7} {11,13} {17,19}.
: n .
1.35.
S = 1/3 + 1/5 + 1/5 + 1/7 + 1/11 + 1/13 + 1/17 + 1/19 +
e , , 1,902160578.
: n -.
1.159. 2
ax + by = c, a, b c . x
y, , .
: d - a b. d c, . x y.
, (x0, y0) [,
, -1995]?
1.160. x % y
,
+,,*,/ .

1 -

134

1.161.
n. , - n,
.
1.162.
n m, m > n,
, n. n
2000.
1.163.
n . , .
1.164. n + 2 = 2m
- n , n + 2 = 2m, m .
1.165.
1, 2, 3,... . 1, 3, 5,
7,... . ( 1, 3, 7, 9, 13) ..
k .
: .
1.166.
n . , .
1.167.
Hn(x):
H0(x) = 1
H1(x) = 2x
Hn(x) = 2x.Hn1(x) 2(n1).Hn2(x), n > 1
1.168.
:
F(n) = F(n1) + F(n2) + F(n3), F(1) = F(2) = F(3) = 1
:
1, 1, 1, 3, 5, 9, 17, ...
, n n- .
. - ? ? n-
.
1.169. p
p :

f i ( 1p ) f i ( p ) f i ( 1p ) ... f i ( pp) , i p
f p( p ) 1
f i ( p ) 0, 0 i p
1.
k p, p k
.

1 -

135

1.170.
, n
n

S
i 1

1 . ,
i

?
1.171. -
- ,
. 6 :
1: ( 1)
2: (1, 2)
4: 3 (1, 2, 4)
6: 4 (1, 2, 3, 6)
12: 6 (1, 2, 3, 4, 6, 12)
24: 8 (1, 2, 3, 4, 6, 8, 12, 24)
n n . ?
1.172. 4k + 3
n. n 4k + 3, kN.
1.173. n!
, :
S = 1 + 2 + 3 + ... + n
, n :
P = 1.2.3. .n = n!
n!, n .
: , - : . , ,
n! :
n! n n e n 2. .n
- , .
1.174. n
n [a, b] ,
a + (a+1) + (a+2) + + b
n. , n = 1986 , , :
[160,171], [495,498] [661,663].
1.175. (n)
n . (n) , - n,
n. (n) n.
, n > 2 (n) ?
(n).
1.176.
n. a, b, c ( ), c < n, a2 + b2 = c2.

1 -

136

1.177. -
n. - P(n) n :
1) n , P(n) = 1.
2) n , P(n) = 1 + P(s), s n
, .. n, -.
, - 36 2. :
36 + 63 = 99
P(48) = 3:
48 + 84 = 132
132 + 231 = 363
P(n) n.
1 250. P(196)?
1.178.
n. n (n ) a, b, c, d, :
a2 +b2 +c2 = d2
: (1,2,2,3).
1.179.
n. n (n ) -

a2 b2 ,

a, b, c ,

a2 c2 ,

b 2 c 2 .

1.180. -
n. n ,
. :
567 = 83 + 33 + 33 + 13 ( 4),
:
567 = 73 + 63 + 23
1.181. 2n
n, 2n 123454321.
1.182.
, n
n 1 2 ( 1.5.2.).

4
3 4
2 3 4
1 2 3 4

5
5
5
5
5

6
6
6
6
6
6

7
7
7
7
7
7
7

9
8 9
8 9
8 9
8 9
8 9
8 9
8 9
8 9

1:
8
8
8
8
8
8
8
8

7
7
7
7
7
7
7

6
6
6
6
6
6

5
5
5
5
5

4
4 3
4 3 2
4 3 2 1

4
3 4
2 3 4
1 2 3 4

5
5
5
5
5

6
6
6
6
6
6

2:
8 8
7 8 8 7
7 8 8 7
7 8 8 7
7 8 8 7
7 8 8 7
7 8 8 7
7 8 8 7

6
6
6
6
6
6

5
5
5
5
5

4
4 3
4 3 2
4 3 2 1

1.5.2. .
1.183.
, n
n ( 1.5.2.).

1
2

1
2
3

1
2
3
4

1
2
3
4
5

1
2
3
4

1
2
3

1
2

1 -

1
2
1

1
2
3
2
1

1
2
3
4
3
2
1

137
2
3
4
5
4
3
2
1

3
4
5
6
5
4
3
2
1

4
5
6
7
6
5
4
3
2
1

5
6
7
8
7
6
5
4
3
2
1

6
7
8
9
8
7
6
5
4
3
2
1

5
6
7
8
7
6
5
4
3
2
1

4
5
6
7
6
5
4
3
2
1

3
4
5
6
5
4
3
2
1

2
3
4
5
4
3
2
1

1
2
3
4
3
2
1

1
2
3
2
1

1
2
1

1.5.2. .

-
1.184.
n nn,
1 n2 , , , ,
, n(n2+1)/2. , n = 5 1.5.2.

17 24 1

23 5

14 16

13 20 22

15

10 12 19 21 3
11 18 25 2

1.5.2. .
: n (n 3) :
1) 1.
2)
. "" , , "" , .
, , "
" . 1.5.2.
, 1:

17 24 1

23 5

14 16

13 20 22

15

10 12 19 21 3
11 18 25 2

1.5.2. .
n , [Magic-1].

1 -

138

1.185.
,
mn (n, m ) ,
. , , , : ; ; ;
.
1.186.
A0 An Ai, i = 1,
2,, n1. A0 An
:
A0 A1 A2 ... An,
Ai Ai+1, i = 0, 1, ..., n1, .
"" "" .
1.187.
nn aij.
A' = {a'ij} , a'ij = aji, 1 i, j n.

-
, , ,
( 1.43.) .
- ( )
, , .
1.188. -2
, -2 6/49.
, , ?
1.189.
1930 . Bell . XX- .
, :
(a1a2a3)b1b2b3c1c2c3c4,
a1 {2,3,...,9}
a2 {0,1}
a3 {0,1,...,9}
b1, b2 {2,3,...,9}
b3, c1, c2, c3, c4 {0,1,...,9}
,
.
1.190.
n nn , :

1 n.

1 n.
, n = 4 1.5.2. .

1 -

139

1.5.2. .
n.
1.191.
2n . , m (ai, bi)
, ai.bi ( i = 1,2,...,m). m .
1.192.
15 . 35
3 . ,
35- ? .
1.193. n-
n, n > 2.
n-. , .
, ,
5.
1.194.
2t + 1 ,
- . , , . .
1.195.
,
( 1.5.2.).

1.5.2. .
n , k , ,
? t
, t.
1.196.
, : 4 13 . , , t

1 -

140


.
1.197.
nn.
n: .. 11, 22, ..., nn?
1.198.
- k , k
?
1.199. n-
n- (n < 11), k,
.
.
1.200.
9 88 ,
, ,
. -
( ).
1.201. MJ-
n .
k (k- , k n) , k/2 k/2 ,
/?
1.202.
, (
VISA MasterCard).
:
16- . :
4204587690125234
1) :
4325210967854024
2) , , :
4 6 2 10 2 2 0 18 6 14 8 10 4 0 2 8
3) , - 9, .
:
4 + 6 + 2 + 1 + 0 + 2 + 2 + 0 + 1 + 8 + 6 + 1 + 4 + 8 + 1 + 0 + 4 + 0 + 2 + 8 = 60
4) 10 , .
4, VISA, 5155, MasterCard.
1.203.
.
: :
: 2, 4, 8, 5, 10, 9, 7, 3, 6.
.
11
. 0 10 0.
, 6 ,
. , , 810229, , 1981
.
: , .

1 -

141

1.204.
() n ,
? n.

1 -

142

2

"A program without a loop and a structured variable
isn't worth writing."
~ Epigrams in programming
- . ,
, ..
, ,
. ,
, . . .
, -
,
, , .
- (/ , ). . ,
, (. .
).
:
, . (. . )
. ,
k- ( , ,
: ). ,
, , , ,
, ,
,
.
.
.
, , ,
. ,
, ,
"".
, ,
, , :
1)

(): ,
, .

2)

: ,
( , ),
, .

2 -

144

, ,
, .
. 52 .
, . :
(
).
( ).
(
).
.
() , ('2', ..., '9', 'T', 'J',
'Q', 'K', 'A') ('S', 'C', 'D', 'H'). 0 51 ( 52).
.
(, 0
51):
int cards[52]. cards[i] 1,
i . cards[i] 0. ,
k, cards[k] = 1;. : k,
cards[k] == 1 cards[k] = 0. k ,
cards[k].
. cards[52]
, 52. . , . (, - 30000)
, , :
int students[30000], 30. : unsigned n, a
, unsigned students[n] , i- (0 i < n)
.
, , , .
,
(, - )
().

2.1. , ,
2.1. ( ) n (n 0)
x1, x2, ..., xn, (). n = 0 .
n > 0, x1 , xn .
:
i (1 i n) i- xi xi-1 xi+1.
"" :
, ., .
, , .

2 -

145

"" ().
- .
, , data
: .
:
struct data {
short age;
char sex;
unsigned fn;
char *name;
};

/*
/*
/*
/*

(- 128 ;) */
'm' 'f' */
*/
*/

, :

k- (
).
() ( ,
)
() k- .
, (
).

, ,
.. - ,

.
, : , - ,
22 , , .
, , ,
, , ,
. .
, -, , ( ).
k = 1 k = n - -
, . ,
/ ,
- :
:
,
, ?

-
, (, ..) , . . . , , (
2.1.).

2 -

data
data
data
data
data
data

146

2.1. .
S :
void init(S);
/* */
void push(S, data x); /* */
data pop(S);
/* */
int isEmpty(S);
/* */

:
, ; / k .
. ( . stack)
. (
) , . , LIFO (Last-In-First-Out
, ).

-
,
, ( 2.1.).
Q :
void init(Q);
void put(Q, data x);
data get(Q);
int isEmpty(Q);

/* */
/* ( ) */
/* (
, ) */
/* */

FIFO (First-In-First-Out
, ) . , (,
) - , -, .

( 2.6.) ..
data
data
data
data
data
data

2.1. .

2 -

147

. , ,
.. , ,
; ;
, ,
.

-
, - , ,
(DEQue, . DoubleEnded-Queue ). ,
.
,
( ) :
( ).
, ( )
( .) [1995].
, .

2.1.1 ()
- ( 2.1.1.). k- addr(k)

addr(k) = addr(k1) + sizeof(data),
sizeof(data) , .
k- .
( baseAddr), k-
, :
addr(k) = baseAddr + (k1).sizeof(data)
: k-, k+1
n . , k- ,
k+1 n . :
n/2 ( ), . .
(n).
data1

baseAddr

data2

data3

...

datak-1

datak

baseAddr + (k-1).sizeof(data)

2.1.1. .

-
. , .

2 -

148

, , . , , . , stack[]
data top, :
#include <stdio.h>
typedef int data;
data stack[10];
int top;
void init(void) { top = 0; }
void push(data i) { stack[top++] = i; }
data pop(void) { return stack[--top]; }
int isEmpty(void) { return(0 == top); }
int main(void) {
/* ... */
return 0;
}

stack1.c
. 10 . 10 ( top 10) , , .
"" ( ) . ,
, top
pop() (
, stack). ,
10, .
20, , ,
, ,
( 9, 101 .).
MAX, .
top - MAX , .
-
.
#include <stdio.h>
#define MAX 10
typedef int data;
data stack[MAX];
int top;
void init(void) { top = 0; }
void push(data i)
{ if (MAX == top)
fprintf(stderr, " ! \n");
else
stack[top++] = i;
}
data pop(void)

2 -

149

{ if (0 == top) {
fprintf(stderr, " ! \n");
return 0;
}
else
return stack[--top];
}
int isEmpty(void) { return (0 == top); }
int main(void) {
data p;
init();
/* 0 */
scanf("%d", &p);
while (0 != p) {
push(p);
scanf("%d", &p);
};
/* .
*
*
*/
while (!isEmpty()) printf("%d ", pop());
printf("\n");
return 0;
}

stack2.c

-
-. , : front, ,
rear, ( 2.1.1.).
...

data

front

data

...

data

rear

2.1.1. .
:

i: i , rear, .
: front,
front .

. , " " :
, front rear
. ,
queue[MAX] ( MAX), ,
- MAX . ,

2 -

150

front rear MAX, 0.


"" queue[] ( 2.1.1.).

rear

front

2.1.1. , .
front rear . , ( ), :
( front
rear), .
(rear front),
MAX .
( ) empty, 1, , 0 .
empty 1 ( ) 0
. -
- , -. :
#include <stdio.h>
#define MAX 10
typedef int data;
data queue[MAX];
int front, rear, empty;
void init(void) { front = rear = 0; empty = 1; }
void put(data i)
{ if (front == rear && !empty) { /* */
/* - , */
fprintf(stderr, "! \n");
return;
}
queue[rear++] = i;
if (rear >= MAX) rear = 0;
empty = 0;
}
data get(void)
{ data x;
if (empty) { /* */
fprintf(stderr, " ! \n");
return 0;
}
x = queue[front++];
if (front >= MAX) front = 0;
if (front == rear) empty = 1;
return x;

2 -

151

}
int main(void) {
data p;
int i;
init();
for (i = 0; i < 2 * MAX; i++) {
put(i);
p = get();
printf("%d ", p);
}
printf("\n");
/* */
for (i = 0; i < MAX + 1; i++) put(i);
/* : */
for (i = 0; i < MAX + 1; i++) get();
return 0;
}

queue.c
:
1. ,
, .
2. : / , .
3. .

2.1.2 ()
.
( ) ,
. ?
( , ): ( 2.1.2a.).
data
link

data
link

.......

data
link

NULL

2.1.2. .
: ,
.
k- ,
k1 . :
typedef int data;
typedef int keyType;
struct list {

2 -

152

keyType key;
data info;
struct list *next;
};

: ( keyType key). info .


struct list *next;
( ; struct
list next; list ).
NULL: *next ,
.
[-1998][-1980].
, : . , .
, :
struct list *L;

L = NULL. , ,
( ) .

-
1)

( 2.1.2.):
struct list:
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));

2)

temp :
temp->next = L;

3)


:
L = temp;
L->key = key;
L->info = x;

2 -

1)

data
link

data
link


2)

data
link

data
link


3)

data
link

link

link

data
link
key, x

link

153

...

data
link

NULL

...

data
link

NULL

...

data
link

NULL

2.1.2. :

-
.
: L,
:
while (L != NULL) {
printf("%d ", L->key);
L = L->next; /* */
}

key:
struct list* search(struct list *L, keyType key)
{ while (L != NULL) {
if (L->key == key) return L;
L = L->next;
}
return NULL;
}

, . ,
, :

- ,
void insertAfter(struct list **L,
keyType key, data x). L (
), key data. :

2 -
1)

154

key x:
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));
temp->key = key;
temp->info = x;

2)

: L, L
( 2.1.2.):
temp->next = (*L)->next;
(*L)->next = temp;

1)
...

data
link

data
link
key, x

L
2)
...

data
link

link

data
link
key, x

link

...

data
link

NULL

...

data
link

NULL

2.1.2. , .

- ,
void insertBefore(struct list **L, keyType key, data
x). , L, ,
( next).
: L -, -,
L.
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));
*temp = **L;
(*L)->next = temp;
(*L)->key = key;
(*L)->info = x;

-
void deleteNode(struct list **L,
keyType key). key.
, , ,
:
(1)
struct list *current = *L;
while (current->next != NULL && current->next->key != key)
current = current->next;

2 -

155

current->next. :
, . . "", , ,
2.1.2.:
(2)
save = current->next;
current->next = current->next->next;
free(save);

...

...

data
link

data
link

data
link

data
link

current current->next
(L)

current->next->next

data
link

data
link

data
link

current

data
link

...

NULL

...

NULL

current->next->next

current->next (L)
( )
2.1.2. .

(1), , ,
key .

- ,
, L,
, L, .
, , .
,
( 2.4.). :
#include <stdio.h>
#include <stdlib.h>
typedef int data;
typedef int keyType;
struct list {
keyType key;
data info;
struct list *next;
};
/* */
void insertBegin(struct list **L, keyType key, data x)
{

2 -

156

struct list *temp;


temp = (struct list *) malloc(sizeof(*temp));
if (NULL == temp) {
fprintf(stderr, " !\n");
return;
}
temp->next = *L;
(*L) = temp;
(*L)->key = key;
(*L)->info = x;
}
/* */
void insertAfter(struct list **L, keyType key, data x)
{ struct list *temp;
if (NULL == *L) {
/* => */
insertBegin(L, key, x);
return;
}
temp = (struct list *) malloc(sizeof(*temp));
/* */
if (NULL == temp) {
fprintf(stderr, " !\n");
return;
}
temp->key = key;
temp->info = x;
temp->next = (*L)->next;
(*L)->next = temp;
}
/* */
void insertBefore(struct list **L, keyType key, data x)
{ struct list *temp;
if (NULL == *L) {
/* */
insertBegin(L, key, x);
return;
}
temp = (struct list *) malloc(sizeof(*temp));
/* */
if (NULL == temp) {
fprintf(stderr, " !\n");
return;
}
*temp = **L;
(*L)->next = temp;
(*L)->key = key;
(*L)->info = x;
}
/* */
void deleteNode(struct list **L, keyType key)

2 -
{ struct list *current = *L;
struct list *save;
if ((*L)->key == key) { /* */
current = (*L)->next;
free(*L);
(*L) = current;
return;
}
/* , */
while (current->next != NULL && current->next->key != key) {
current = current->next;
}
if (NULL == current->next) {
fprintf(stderr, ": ! \n");
return;
}
else {
save = current->next;
current->next = current->next->next;
free(save);
}
}
/* */
void print(struct list *L)
{ while (NULL != L) {
printf("%d(%d) ", L->key, L->info);
L = L->next;
}
printf("\n");
}
/* */
struct list* search(struct list *L, keyType key)
{ while (L != NULL) {
if (L->key == key) return L;
L = L->next;
}
return NULL;
}
int main(void) {
struct list *L = NULL;
int i, edata;
insertBegin(&L, 0, 42);
for (i = 1; i < 6; i++) {
edata = rand() % 100;
printf(" : %d(%d)\n", i, edata);
insertBefore(&L, i, edata);
}
for (i = 6; i < 10; i++) {
edata = rand() % 100;
printf(" : %d(%d)\n", i, edata);
insertAfter(&L, i, edata);
}

157

2 -
print(L);
deleteNode(&L,
deleteNode(&L,
deleteNode(&L,
deleteNode(&L,
deleteNode(&L,
return 0;

9);
0);
3);
5);
5);

158

print(L);
print(L);
print(L);
print(L);

list.c
:
: 1(46)
: 2(30)
: 3(82)
: 4(90)
: 5(56)
: 6(17)
: 7(95)
: 8(15)
: 9(48)
5(56) 9(48) 8(15) 7(95) 6(17) 4(90)
5(56) 8(15) 7(95) 6(17) 4(90) 3(82)
5(56) 8(15) 7(95) 6(17) 4(90) 3(82)
5(56) 8(15) 7(95) 6(17) 4(90) 2(30)
8(15) 7(95) 6(17) 4(90) 2(30) 1(46)
:

3(82) 2(30) 1(46) 0(42)


2(30) 1(46) 0(42)
2(30) 1(46)
1(46)
!

:
1. ,
, .
2. , , ..
. ,
, . (,
) .
3. ,
. , ,
, .
, .
? ? ?

2.2.
,
- , :
, , .
, ( (1)), , (n).
(1), , (n). , - ( ).
( ),
( 4 4.3.) -

2 -

159

(log2n) ( , 2.6.).
,
k- .
, . , , .
2.2. T (- ),
, :
1) t, , root(T).
2) ( ) m (m 0)
T1, T2, ..., Tm, .
T1, T2, ..., Tm T. t1 T1, t2 T2, ..., tm Tm
t. T1, T2, ..., Tm
t.
(-,
) .
. 0, .

2.2. .

( A (B(D)(E)(F)) (C) )
2.2. .

2.2. ( 5).

2.2. ( 5),
: .

2 -

160

A
B
D
E
F
C
2.2. .
2.2., 2.2., 2.2., 2.2. 2.2. . T = {A, B, C, D, E, F}, : A
, T1 = {C} T2 = {B, D, E, F} ( C ). T2 = {B,
D, E, F} B, {D},{E},{F} (D, E F ).
2.3. t1, t2, ..., tk ,
ti1 ti (2 i k) e : ti ti1, ti1 ti. k1 .
. .
2.4. .
.
2.5. - , . - , -
( ): .
, , , . 2.2. ,
2.2.

2.2. .

b
2.2. .
. :
, .
( 2.2.):
.
, .
, 2.2. .

2 -

161

, , t1
t2, t1 t2.
, 2.2.?
,
.

2.2. -K. [-II].

2 -

162

*
c

2.2. a+((c*d)*(eb)).
T, t
( 2.2.):
key(t) .
data(t) .
left(t) right(t): t
typedef char *data;
typedef int keyType;
struct tree {
keyType key;
data info;
struct tree *left;
struct tree *right;
};

data
data
left link

data
left link
right link

right link

data
left link

right link

left link

.......

right link

NULL

data
left link
right link

.......

.......

.......

2.2. .

:

void insertKey(keyType key, data x, struct tree **T)


void deleteKey(keyType key, struct tree **T);

NULL

( )
struct tree *search(keyType key, struct tree *T);

NULL

2 -

163

6
5
3

10
8

13

14

11

12
2.2. .
.
- ,
.
2.6. ( )
, : -
, - ( , ,
) .
2.2. (
). , - ,
, - .
( ).
- :

-
, . . t = root(T);
search(key, t):
1) key < key(t), t, . .
search(left(t), key);
2) key > key(t), t, . . search(right(t), key);
3) key == key(t), .
, , , .
, , , ,
, (. . NULL). ,
2.2. 9,
:
9 > 6 10.
9 < 10 8.
9 > 8 , NULL, .

2 -

164

-
,
, .
insert(t, p):
1) t == NULL , p
: t = p;
2) key(p) < key(t) insert(left(t), key );
3) key(p) > key(t) insert(right(t), key );
4) key(p) == key(t) , , , .
: ,
(. . ).

-
-. , k
, . . 3 :

, ( NULL).
, .
- , p
. : -
(- ) p.
p - .
( , :
- , p ..)
2.2. 2.2.

6
5
3

6
10

8
7

3
1

13

14

11

10
8

12
2.2. 5.

13

14

11

12

2 -

165

6
5
3
1

8
7

10
3

13

14

11

8
7

11
3

13

14

10

12

12

2.2. 10.
- :
#include <stdio.h>
#include <stdlib.h>
typedef char *data;
typedef int keyType;
struct tree {
keyType key;
data info;
struct tree *left;
struct tree *right;
};
/* */
struct tree *search(keyType key, struct tree *T)
{ if (NULL == T)
return NULL;
else if (key < T->key)
return search(key, T->left);
else if (key > T->key)
return search(key, T->right);
else
return T;
}
/* */
void insertKey(keyType key, data x, struct tree **T)
{ if (NULL == *T) {
*T = (struct tree *) malloc(sizeof(**T));
(*T)->key = key;
(*T)->info = x;
(*T)->left = NULL;
(*T)->right = NULL;
}
else if (key < (*T)->key)
insertKey(key, x, &(*T)->left);
else if (key > (*T)->key)
insertKey(key, x, &(*T)->right);
else
fprintf(stderr, " !\n");

10
8

13

12

14

2 -
}
/* */
/* */
struct tree *findMin(struct tree *T)
{ while (NULL != T->left) T = T->left;
return T;
}
void deleteKey(keyType key, struct tree **T)
{ if (NULL == *T) {
fprintf(stderr,", , !\n");
} else {
if (key < (*T)->key)
deleteKey(key, &(*T)->left);
else if (key > (*T)->key)
deleteKey(key, &(*T)->right);
else /* */
if ((*T)->left && (*T)->right) {/* */
/* */
struct tree *replace = findMin((*T)->right);
(*T)->key = replace->key;
(*T)->info = replace->info;
deleteKey((*T)->key, &(*T)->right); /* */
}
else { /* */
struct tree *temp = *T;
if ((*T)->left)
*T = (*T)->left;
else
*T = (*T)->right;
free(temp);
}
}
}
void printTree(struct tree *T)
{ if (NULL == T) return;
printf("%d ", T->key);
printTree(T->left);
printTree(T->right);
}
int main(void) {
struct tree *T = NULL, *result;
int i;
/* 10 */
for (i = 0; i < 10; i++) {
int ikey = (rand() % 20) + 1;
printf(" %d \n", ikey);
insertKey(ikey, "someinfo", &T);
}
printf(": ");
printTree(T);
printf("\n");

166

2 -

167

/* 5 */
result = search(5, T);
printf(" : %s\n", result->info);
/* 10 */
for (i = 0; i < 10; i++) {
int ikey = (rand() % 20) + 1;
printf(" %d \n", ikey);
deleteKey(ikey, &T);
}
printf(": ");
printTree(T);
printf("\n");
return 0;
}

bintree.c
:
1
1
!
7
1
!
8
5
11
4
15
19
: 1 7 5 4 8 11 15 19
: someinfo
6
, ,
9
, ,
3
, ,
14
, ,
12
, ,
1
4
17
, ,
14
, ,
16
, ,
: 7 5 8 11 15 19

!
!
!
!
!

!
!
!

2 -

168

-
, -
printTree(struct tree *T).
: , (!)
, T.
( 5),
,
.
.
.
-- ( . preorder). ,
, :

(. inorder): : , .
(. postorder):
.

. , inorder
, , ,
.
2.2. :
: +a**cdeb
: a+c*d*eb
: acd*eb*+
""
:

: +*be*dca
: be*d*c+a
: bedc**a+

6: ,
(), () (). ,
( ,
, ?),
.
, ,
(
, a, c, d, e f) [-1980][-1998].
:
1.
:
) 7, 14, 28, 35, 65, 12, 18, 42, 81, 64, 61, 4, 13
) 12, 7, 14, 81, 42, 18, 61, 4, 64, 35, 13, 28, 65
) 4, 7, 12, 13, 14, 18, 28, 35, 42, 61, 64, 65, 81
) 81, 65, 64, 61, 42, 35, 28, 18, 14, 13, 12, 7, 4
) 28, 64, 13, 42, 7, 81, 61, 4, 12, 65, 35, 18, 14
. ?
2. 8, 13, 5 6 2.2.

2 -

169

3. (A+BC)*(D/F)G*H. .
4. , .
5. - 2.2. ,
2.2.?
6. .
7. , , .
8.
.
9. -
- . ,
- . ?
10. .
11. - ,
, . , ( +, , *, /),
, . ()
: + ? ?

2.3.
- ,
,
, . , , n . ""
, (
2.3.):
2, 3, 5, 8, 11, ...
2
3
5
8
11
...

2.3. - .
"" , , ,
. ,
, - .
, "" , (, , ) .

2 -

170

2.7. ,
- .
2.8. n , - .
2.9. Tk k, , :
T0 0;
T1 , 1;
k 2 , Tk-1 k1 (
) Tk-2 k2 ( ).
2.3. 0.

2.3. 1.

2.3. 2.

2.3. 3.

2 -

171

2.3. 4.

2.3. 5.
2.3, 2.3., 2.3., 2.3., 2.3.
2.3. , - ,
. :
. (, ) n .
h . :

log 2 (n 1) h 1,4404. log 2 (n 2) 0,3277


? , h
2h , . . n + 1 2h, h log 2 (n 1) .
h , Th , :
Th h . Th , (

2 -

172

) Th h1, : h1
h2. Th , Th
Th1, : Th2. , h
h+1 (?). n Fh + 2, [Knuth3/1968]:
Fh+21 > h 2 / 5 2
.
.
"" :
.
- k-.
, ,
.
:
1.
{4, 7, 12, 13, 14, 18, 28, 35, 42, 61, 64, 65, 81}.
2. :
) 2.2.
) 2.2.
) 2.2.
3. :
) 2.2.
) 2.2.
) 2.2.

2.3.1. . -
,
(), ,
"". , . ( 2.3.1.).
:
;
;
( ) .
, , , . .. - ( . Red-Black Tree).
2.10. - ,
,
:
( NULL, ) .
, .
t t .

2 -

(A)

()

173

a
a

b
b

c
1

2
1

3
1

2
1

()

()

c
1

2
3
3
2
1
1
2.3.1. (), (), - () - () .

34
7
22

12

45
7
17

37

15

2.3.1. - .
2.10. :
- n - 2.log2(n+1), . . -
.
. , ,
- 1. -
- . -
(, , )
(log2n), -
[-1995] [Cormen, Leiserson, Rivest-1997].

AVL- ( Adelson-Velskii Landis), -

2 -

174

- [-1980][Knuth-3/1968].
AVL- - -
-, -.
:
1. 2.10., , -
.
2.
- .

2.3.2. B-
(
) - .
2.11. k- , k1 ( + ) t1 < t2 < ... < tk1 k
T1, T2 ,..., Tk , ti, i = 1,2,..., k1,
: Ti - ti
Ti+1 - ti.
2.12. 2-3-4 T :

T .

(. . ) 2-, 3-, 4-.

.
30 50 63

32 36 41

12

16 18

70

54

43

10 15

44 47

65 67

52

72

56

2.3.2. 2-3-4 .
2-3-4 ,
(, , ) (log2n).
, 2-3-4 ( - - ),
- - ,
2-3-4 - [Flamig-1993].
2-3-4 .
2.13. B- m
:
, , k-, k [m/2] m.

2 -

175

2.13. B-
. , m = 4 2-3-4-.
18 70

10 12

22 35 45

11

14 16 17 18

2.3.2. B- 5.
- B-.
B- [-1980][-1995][Knuth-3/1968].
B- , ( ). ,
. ,
4096 .
.
, - ,
,
. ,
, ,
. :
, . ,
. ,
, . , ,
, ,

B-
: k- B- [m/2]1 m1 . m , ( ). B- ,
- h = log[m/2]((n+1)/2), - m , n. , (h) h
B-.
,
. . Oracle B . Windows
Microsoft B-,
.
:
1. , B- .

2 -

176

2. B-, - .
3. B-
.

2.4. -
- , , . (,
, ) ,
. -
:

void put(key, data);


data get(key);
void remove(key);

, , : key data.
: , .
- n- , i (i = 0,1,...,n1) i- . , () . , ,
( ).
, - (. .
).
,
, .

- -
, ,
. , (10- , .
, ,
.) ( , ,
). - : ,
10- . a[] n ( n
-). , - n,
a[]. , (-),
0 n1.
( 1), 0 n1,
, , ""
.
1. - n U (). - :
h : U {0,1,...,n1}
, 10- k ()
0 n1 k % n. , k
-, -.

2 -

177

-: ,
. , k1 = 8004104369, k2 = 8004102469
n = 100 : k1 % n = k2 % n = 69, . .
-. .

1
1

2
2

n-1

m
m

2.4. -, - (-).

-
2. - h k1, k2U h(k1) = h(k2),
, k1 k2 . , .
, - :
, ,
.
( , ): n .
n+1 , .
-, - , - ( ).
- ( , ).
" ": 23
, (. . )? ,
1 : 1

23

i 2

366 i = 0,5063.
365

? A
. 1P(A). P(A),
:
. (
A) , ( 23) ,
365.364.363...343 . ,
36523. . ,
, .
, 365 , .. .

2 -

178

, -, ..
, .
- -, -
. 2.5.3. -.

2.4.1. -
- : -
-. , . ,
: ,
, ASCII-. , "hello"
104+101+108+108+111 = 532. , ,
ASCII ASCII 'a'.
, . , . ,
- -;
-. ,
.
, :
a1a2an , b-
( b ).
- n k. - - ( ).

-
-
k n .
- n, : n = 2p,
- k p k. , n = 24 = 16 k = 173.
173 10101101. 173 % 16 13, ,
, 1101 .. 4 173. ( 1.1.6.)
, , . , -
. - -
.

-
.
, 0 < < 1. k - :
h(k) = n. {k.a}
{k.a} , . . k.a k.a.
a ( 0 < < 1) ,
-. [Knuth-3/1968] a
( 1.2.2.):
a=

5 1 = 0,6180339887....
2

2 -

179

- -
-
,
(, , ).
123569, 425435, 546754, 676576 - 136, 453, 565, 667. ,
n 1000 ( 1, 3 5-
[0, 999]). , .
-
-, .
,
. ,
( ) -.
-
p
. , 125657134280980 134. : 134.134 = 17956. n, :
, n = 10001, 17956 - 7956.
, n.

- -
:
- n m ,
( ,
). -
- -.
2

f i , fi

m i 1
n

( m = 1031000, n = 1031) 2.4.1., 2 n

-, i.
-
1031
(, 3
)
( 1-3-3-3
)
,
.

2
729
352
735
233

2.4.1. 2 - , n = 1031, m = 1031000.


2 , - (. .
, , )
m > c.n, 2 n n 11/c.
, ( ) n = 1031 m = 1031000
-, - .

2 -

180

- -
- . - . - -
- , . . - :
result =
while (c
result
result
}
result =

();
= _()) {
= (result, c);
= _(result);
_(result);

-
-, - (), - . ASCII .
unsigned long hashFunction(const char *key, unsigned long size)
{ unsigned long result = 0;
while (*key)
result += (unsigned char) *key++;
return result % size;
}

, :
unsigned long hashFunction(const char *key, unsigned long size)
{ unsigned long result = strlen(key);
while (*key)
result += (unsigned char) *key++;
return result % size;
}

, , strlen(). ( -, - result
):
unsigned long hashFunction(const char *key, unsigned long size)
{ const char *saveKey = key;
unsigned long result = 0;
while (*key)
result += (unsigned char) *key++;
result += saveKey key;
return result % size;
}

- .
2, :

2 -

181

return result & (size - 1);

-:
hash = (hash ^ (hash>>10) ^ (hash>>20)) & mask;

-, .
-
, .
.
unsigned long hashFunction(const char *key, unsigned long size)
{ unsigned long result = strlen(key);
while (*key)
result = (result << 4) ^ (result >> 8) ^ ((unsigned char) *key++);
return result % size;
}

-
result,
.
unsigned long hashFunction(const char *key, unsigned long size)
{ unsigned long result = 0;
while (*key) {
result += (unsigned char) *key++;
result += result << 10;
result ^= result >> 6;
}
result += result << 3;
result ^= result >> 11;
result += result << 15;
return result % size;
}

-
tab[], 0 255.
, - : 0 255. - ,
tab[],
.
unsigned char hashFunction(const char *key, unsigned long size,
const unsigned char tab[])
{ unsigned long result = strlen(key);
while (*key)
result = tab[result ^ ((unsigned char) *key++)];
return result;
}

- CRC
Linear Feedback Shift
Register. , , ,
, .
unsigned long hashFunction(const char *key, unsigned long size,

2 -

182

const unsigned long tab[])


{ unsigned long result = strlen(key);
while (*key)
result = (result<<8) ^ tab[(result>>24) ^ ((unsigned char) *key++)];
return result % size;
}

- CRC
, tab[] .
-
- , , - (n),
n -. , , .
, - ?
:
.
, . . , 1/n.
? -,
. , ?
m (m = |U|),
f. f/m = 1/n. .. m/n ,
.
2.16. H = a {ha} - -, :
|H| = m/n m/n ha
P(ha(x) = ha(y)) = 1/n 1/n
- m/n
, (a , ):

ha (k ) ai k i mod n
i 0

:
k = (k0, k1, .., kr) k r+1 ( )
a = (a0, a1, .., ar), , {0, 1, .., n1}.
. tab[] , , {0, 1, .., n1}.
.
unsigned long hashFunction(const char *key, unsigned long size,
const unsigned long tab[MAXBITS])
{ unsigned char k;
unsigned i;
unsigned long result;
unsigned long l3 = (result = strlen(key)) << 3;
for (i = 0; i < l3; i += 8)
{
k = (unsigned char) key[i >> 3];
if (k&0x01) result ^= tab[i+0];
if (k&0x02) result ^= tab[i+1];
if (k&0x04) result ^= tab[i+2];
if (k&0x08) result ^= tab[i+3];

2 -
if
if
if
if

(k&0x10)
(k&0x20)
(k&0x40)
(k&0x80)

result
result
result
result

^=
^=
^=
^=

183

tab[i+4];
tab[i+5];
tab[i+6];
tab[i+7];

}
return result % size;
}

- -
tab[][] ,
{0, 1, .., n1}. .
unsigned long hashFunction(const char *key, unsigned long size,
const unsigned long tab[MAXBYTES][256])
{ unsigned i;
unsigned long result = strlen(key);
for (i = 0; i < len; i++)
result ^= tab[i][*key++]
return result % size;
}

:
1. - :


2. - ?
3. - ?
4. , -, ?
5. - .
6. m/n -, (a ,
):

ha (k ) ai ki mod n
i 0

:
k = (k0, k1, .., kr) x r+1 ( )
a = (a0, a1, .., ar), , {0, 1, .., n1}.
n -
m
2.16., , -.
7. 2.4.1. .
8. ( )
, - (
, n m)? 2 n n , -,
?
9. n m.
?
1.203.
10.
2.4.1. ( , ...)?
?
?

2 -

184

2.4.2.
.
- n = 10. -,
-. , , , 234, 235, 567, 123, 534 647.

-
-
, -
, .
, (n "",
). ,
-, "". .
, s (0 < s < n).
n, -,
n.
-, n s , . . (n, s) = 1.
, , - ( 2.4.2.) ,
( - ).
- - (
2.5.3).

234,
0
1
2
3
4
5
6
7
8
9

234

:
235,
567,
534,

234
235

123,

647

234
235

234
235

123
234
235

123
234
235

56 7

567
534

567
534

567
534
647

2.4.2. .
1.
- - , ,
( ), . , -.
s = 1:
.. 1. , -, ,
. ,
- (. . "").

2 -

185

() ( 2.4.2.). -
.

-
, ,
c1i + c2i2, c2 0. i.
- , , ( ).
, , ..
, . [Cormen, Leiserson, Rivest-1997].

-
, , :
h(k, i) = h1(k) + i.h2(k)
i . -
, .
, -, -.

-
-
,
. , ,
( 2.4.2.).
234,
0
1
2
3
4
5
6
7
8
9
10
11

234

:
235,
567, 534,

123,

647

234

234

123
234

123
234

567

567

567

567
647

235

235

235
534

235
534

235
534

234

2.4.2. .
- , -, ,
, .

2 -

186

-
0

NULL

123

NULL

234

235

NULL

NULL

NULL

567

534

NULL

647

NULL

NULL

NULL

NULL

2.4.2. : -,
234, 235, 567, 123, 534, 647.
, -
: -
. - , - , . :
- ,
.
, , - ( 2.4.2.). T
. , ,
-.
, , . .
.
, - .
- .
:
1. : .
?
2. ?
?

2.4.3. -
-. ( -,
). ,
. ( , , - ).
- N . .
#include <stdio.h>

2 -
#include <stdlib.h>
#define N 211
typedef int data;
typedef long keyType;
#define NOT_EXIST (1) /* get(), */
struct list {
keyType key;
data info;
struct list *next;
};
struct list *hashTable[N];
/* */
void insertBegin(struct list **L, keyType key, data x)
{
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));
if (NULL == temp) {
fprintf(stderr, " !\n");
return;
}
temp->next = *L;
(*L) = temp;
(*L)->key = key;
(*L)->info = x;
}
/* */
void deleteNode(struct list **L, keyType key)
{ struct list *current = *L;
struct list *save;
if ((*L)->key == key) { /* */
current = (*L)->next;
free(*L);
(*L) = current;
return;
}
/* , */
while (current->next != NULL && current->next->key != key)
current = current->next;
if (NULL == current->next) {
fprintf(stderr, ": ! \n");
return;
}
else {
save = current->next;
current->next = current->next->next;
free(save);
}
}
/* */

187

2 -

188

struct list* search(struct list *L, keyType key)


{ while (L != NULL) {
if (L->key == key) return L;
L = L->next;
}
return NULL;
}
unsigned hashFunction(keyType key)
{ return(key % N); }
void initHashTable(void)
{ unsigned i;
for (i = 0; i < N; i++) hashTable[i] = NULL;
}
void put(keyType key, data x)
{ int place = hashFunction(key);
insertBegin(&hashTable[place], key, x);
}
data get(keyType key)
{ int place = hashFunction(key);
struct list *l = search(hashTable[place], key);
return (NULL != l) ? l->info : NOT_EXIST;
}
int main(void) {
initHashTable();
put(1234, 100);
put(1774, 120);
put(86, 180);
printf("
printf("
printf("
printf("
return 0;
}

/* -> 179 */
/* -> 86 */
/* -> 86 -> */

86: %d
1234: %d
1774: %d
1773: %d

\n",
\n",
\n",
\n",

get(86));
get(1234));
get(1774));
get(1773));

hash.c
:

86: 180
1234: 100
1774: 120
1773: -1

,
, -. : , -, .
: ( ), .
.
- . , (. Google), ,
.

2 -

189

-, :

- . .
. -.

, - n
2. ,
, . . abc bca -. -,
2.5.1.,
, , -
. ,
,
, - .
-
- ,
. s (s > 2), , :
, n s .

- ,
: 2.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S 107
/* */
#define MAX_FILL_LEVEL 0.8 /* */
unsigned long n = 32;
/* - */
struct singleWord {
char *word;
unsigned long freq;
} *ht;

/* - */
/* */

unsigned long count;


/* - */
unsigned long hashFunction(const char *key)
{ unsigned long result = 0;
while (*key)
result += result + (unsigned char) *key++;
return result & (n - 1);
}
/* - */
void initHashtable(void)
{ unsigned long i;
count = 0;
ht = (struct singleWord *) malloc(sizeof(*ht)*n);
for (i = 0; i < n; i++)
ht[i].word = NULL;
}
/* -: 1 , 0 */
/* : *ind */

2 -
/* : , */
char get(const char *key, unsigned long *ind)
{ unsigned long k;
*ind = hashFunction(key);
k = *ind;
do {
if (NULL == ht[*ind].word) return 0;
if (0 == strcmp(key, ht[*ind].word)) return 1;
*ind = (*ind + S) & (n - 1);
} while (*ind != k);
return 0;
}
/* - */
void resize(void)
{ unsigned long ind, hashInd;
struct singleWord *oldHashTable;
/* 1. - */
oldHashTable = ht;
/* 2. */
n <<= 1;
/* 3. - */
ht = (struct singleWord *) malloc(sizeof(*ht)*n);
for (ind = 0; ind < n; ind++)
ht[ind].word = NULL;
/* 4. - */
for (ind = 0; ind < (n >> 1); ind++) {
if (oldHashTable[ind].word != NULL) {
/* */
if (!get(oldHashTable[ind].word, &hashInd))
ht[hashInd] = oldHashTable[ind];
else
printf(" -!\n");
}
}
/* 5. */
free(oldHashTable);
}
/* - */
void put(char *key)
{ unsigned long ind;
if (!get(key, &ind)) { /* - */
ht[ind].word = strdup(key);
ht[ind].freq = 1;
if (++count > ((unsigned long) n * MAX_FILL_LEVEL)) resize();
}
else
ht[ind].freq++;
}
/* - */
void printAll(void)
{ unsigned long ind;

190

2 -

191

for (ind = 0; ind < n; ind++)


if (ht[ind].word != NULL)
printf("%s %ld \n", ht[ind].word, ht[ind].freq);
}
/* - */
void destroy(void)
{ unsigned long ind;
for (ind = 0; ind < n; ind++)
if (ht[ind].word != NULL) free(ht[ind].word);
free(ht);
}
int main(void) {
unsigned long find;
initHashtable();
put("reload");
put("crush tour");
put("room service");
put("load");
put("reload");
put("reload");
printAll();
if (get("reload", &find))
printf(" 'reload': %d \n", ht[find].freq);
else
printf(" 'reload' !");
if (get("download", &find))
printf(" 'download': %d \n", ht[find].freq);
else
printf(" 'download' !");
destroy();
return 0;
}

hashset.c
:
load 1
reload 3
crush tour 1
room service 1
'reload': 3
'download' !

:
1. - .
. ,
,
: -, ..
.

2 -

192

2. - 2.4.3.
( ) ,
(), ?
3. "" -: ,
. ? ? ?
4. - - 80%:
. ,
- - 2.

-. : 85%, 90%, 93%, 95%, 97%, 98%,
99%, 100%?
5. - -
:
result += result + (unsigned char) *key++;

- :
result = result + (unsigned char) *key++;

,
, -.
6. - .

.
?
-? ?
2?
7. - .
?

2.5.
2.5.1.
2.1.
,
, ? ( 2.1.)
2.2.
2.1.1. ,
, .
2.3.
2.1.1.: /
, .
2.4.
. ( 2.1.1.)
2.5.
2.1.2. ,
, .

2 -

193

2.6.
, , .. . ,
2.1.2.,
. (,
) .
2.7.
, . , ,
, .
, .
? ? ? ( 2.1.2.)
2.8.
:
) 7, 14, 28, 35, 65, 12, 18, 42, 81, 64, 61, 4, 13
) 12, 7, 14, 81, 42, 18, 61, 4, 64, 35, 13, 28, 65
) 4, 7, 12, 13, 14, 18, 28, 35, 42, 61, 64, 65, 81
) 81, 65, 64, 61, 42, 35, 28, 18, 14, 13, 12, 7, 4
) 28, 64, 13, 42, 7, 81, 61, 4, 12, 65, 35, 18, 14
. ? ( 2.2.)
2.9.
8, 13, 5 6 2.2.
2.10.
(A+BC)*(D/F)G*H. . ( 2.2.)
2.11.
, . ( 2.2.)
2.12.
- 2.2. ,
2.2.?
2.13.
. (
2.2.)
2.14.
, , . ( 2.2.)
2.15.
2.2.
.
2.16.
2.2.
- . ,
- . ?
2.17.
. ( 2.2.)

2 -

194

2.18.
2.2. ,
, . , ( +, , *, /),
, . ()
: + ? ?
2.19.

{4, 7, 12, 13, 14, 18, 28, 35, 42, 61, 64, 65, 81}. ( 2.3.)
2.20.
( 2.3.):
) 2.2.
) 2.2.
) 2.2.
2.21.
( 2.3.):
) 2.2.
) 2.2.
) 2.2.
2.22.
2.10., , -
. ( 2.3.1.)
2.23.
. ( 2.3.1.)
2.24.
, B- . ( 2.3.2.)
2.25.
B-, - . ( 2.3.)
2.26.
B-
. ( 2.3.2.)
2.27.
2.4.1. :


2.28.
- ? ( 2.4.1.)
2.29.
2.4.1. -
?
2.30.
, -, -?
( 2.4.1.)

2 -

195

2.31.
- ( 2.4.1.).
2.32.
m/n -, (a ,
):

ha (k ) ai xi mod n
i 0

:
k = (k0, k1, .., kr) x r+1 ( )
a = (a0, a1, .., ar), , {0, 1, .., n1}.
n -
m
2.16., , -.
2.33.
2.4.1. .
2.34.
( ) 2.4.1.
, -
, n m? 2 n n , -,
?
2.35.
2.4.1. n m. ?
1.203.
2.36.
2.4.1. ( , ...)?
? ?
2.37.
: .
? ( 2.4.2.)
2.38.
?
? ( 2.4.2.)
2.39.
- . . ,
, : -, ..
. ( 2.4.)
2.40.
- 2.4.3.
( ) ,
(), ?

2 -

196

2.41.
"" -: ,
. -? ? ? ( 2.4.3.)
2.42.
2.4.3. - 80%:
. ,
- - 2.

-. : 85%, 90%, 93%, 95%, 97%, 98%,
99%, 100%?
2.43.
2.4.3. -
:
result += result + (unsigned char) *key++;

- :
result = result + (unsigned char) *key++;

,
, , -.
2.44.
2.4.3. .

.
? -? ?
2?
2.45.
2.4.3. .
?

2.5.2.
2.46.
. :
typedef int data;
typedef int keyType;
struct list {
keyType key;
data info;
struct list *prev;
struct list *next;
};

(
) ( prev).

( , ), ( )
, .

2 -

197

2.47.
,
next .

.
2.48.
( .). ,
, , .
, , , - ( , ).
- , -
.
- .
, (log2n) [-1998][-1980].
: , 3.1.9. . ,
(
5.4.2.), .
2.49. ""
, , .. "" . , ,
"" . ,
"" , , , . ,
.
. ,
(,
""), "" .
2.50.
, , . [-1998].
2.51.
, , , .
: [-1998].
2.52.
,
( ); { }; [ ]; /* */ .
: .
2.53.
,
( /
: ,
, - ).
.
:

.
. (?)

2 -

198

: ,
. , .
, , , :
.
n- . , 1.2.2.
( 7.8.).
2.54.
:
p(x) = anxn + an1xn1 + ... + a1x + a0
, .
, , , , x [-1998].
2.55.
2.3. ,
. ,
?
2.56.
,
.
2.57. -
, ,
.
2.58.
{, }.
[-1998].
2.59.
, , .
: ,
, [-1998].
2.60.
, .
2.61.
t1 t2.
x , [t1, t2], . . t1 key[x] t2.

... there are many best methods, depending on what is to


be sorted, on what machine, for what purpose.
~ D.E.Knuth

- . 4,
- ,
.
( )
.
: , , , .
, , , .. .
- .
, ( ) ( 800 )
( [Knuth-3/1968]).
, , +
= ( [-1980]).
. - . ,
( -
) (
- ,
). , ,
(- <, > =)
( , ).
. . ,
.
,
. , :
, .
: 1) , 2) .
( ) ,
( ) .
, - , - . -.
M
a1, a2, ..., an,
f, .
M
ai1, ai2, ..., ain
, :
f(ai1) f(ai2) ... f(ain).

3 -

200

f . ,
(, ) .
, , - ,
:
#define MAX 100
struct CElem {
int key;
/* .............

............. */
} m[MAX];

, , ,
. -
, .

. .
. -
:
/* *x1 *x2 */
void swap(struct CElem *x1, struct CElem *x2)
{ struct CElem tmp = *x1; *x1 = *x2; *x2 = tmp; }

3.1.
, . ,
< (), > () = ().

3.1.1.
a<b

b<c

b<c

a<b<c

a<c

a<cb

a<c

ca<b

ba<c

cba

b<ca

3.1.1. {a, b, c}.


- . , .
.
.
, x < y : , x - y,
. ,
,

3 -

201

. 3.1.1. {a, b, c}.


:
if (a < b)
if (b < c) printf(a,b,c);
else
if (a < c) printf(a,c,b);
else printf(c,a,b);
else
if (b < c)
if (a < c) printf(b,a,c);
else printf(b,c,a);
else printf(c,b,a);

, 1)
(?), 2) ( :
3.1.10.). , , . , ( ) n!,
, ,
, , .
- .
:
, - .

3.1.2.
: , .
, . ( 20) . , - , . ,
(n2), - (n.log2 n), ( 3.1.9.)
( 3.1.6.). , ,
- , -,
. ,
,
- .
,
, ,
. ( ) .
. struct CElem
key, . .
,
. n1 . i- , (i+1)- (

3 -

202

x) , . .
1 i.
? x .
( 3.1.2.):
1) , - x;
2) .
4
1
3
5
2

1
4
3
5
2

1
3
4
5
2

1
2
3
4
5

3.1.2. .
. , m[0].
void straightInsertion(struct CElem m[], unsigned n)
{ struct CElem x;
unsigned i;
int j;
for (i = 0; i < n; i++) {
x = m[i];
j = i-1;
while (j >= 0 && x.key < m[j].key)
m[j+1] = m[j--];
m[j+1] = x;
}
}

insert_s.c
. .
, -
. , x . (?)
(
1,2,...,n):
void straightInsertion(struct CElem m[], unsigned n)
{ unsigned i, j;
struct CElem x;
for (i = 1; i <= n; i++) {
x = m[i]; m[0].key = x.key;
for (j = i - 1; x.key < m[j].key; j--)
m[j+1] = m[j];
m[j+1] = x;
}
}

inserts2.c

n1

(n2+n2)/4

(n2+n)/21

3 -

203
2(n1)

(n2+9n10)/4

(n2+3n4)/2

3.1.2. .
, ,
(, ,
), n2.
3.1.2.
[Knuth-3/1968][-1980].
? , .
, ( 4.3.), , x i- , log2 i:
void binaryInsertion(struct CElem m[], unsigned n)
{ struct CElem x;
unsigned i, med, r;
int j, l;
for (i = 1; i < n; i++) {
x = m[i];
l = 0;
r = i - 1;
/* */
while (l <= (int)r) {
med = (l + r) / 2;
if (x.key < m[med].key)
r = med - 1;
else
l = med + 1;
}
/* . */
for (j = i - 1; j >= l; j--)
m[j + 1] = m[j];
m[l] = x;
}
}

insert_b.c
, , ,
,
. , .
:
1. , , , .
2. .
3. 3.1.2.

3.1.3. .

1959 .
.
, 1.

3 -

204

xk , xk+, xk+2,
... (1 k ) -. s, s1, ..., 1,

s > s1 > ... > 1 = 1.
s-, s1-, ...,
1- . ,
-, - ( < ),
-. (?) , i- ,
1 .
- , .
. s , s . ,
.
, : shellSort() shellSort(m,
MAX), shellSort(m + steps0 + 1, MAX).
#define MAX 100
#define STEPS_CNT 4
#define steps0 40
const unsigned steps[STEPS_CNT] = { steps0, 13, 4, 1 };
struct CElem {
int key;
/* .............

............. */
};
..................
void shellSort(struct CElem m[], unsigned n)
{ int i,j,k,s;
unsigned stepInd;
struct CElem x;
for (stepInd = 0; stepInd < STEPS_CNT; stepInd++) {
s = -(k = steps[stepInd]); /* */
for (i = k + 1; i <= (int)n; i++) {
x = m[i];
j = i - k;
if (0 == s)
s = -k;
m[++s] = x;
while (x.key < m[j].key) {
m[j + k] = m[j];
j -= k;
}
m[j + k] = x;
}
}
}
..................

3 -

205

int main(void) {
struct CElem m[MAX + steps0 + 2];
..................
shellSort(m + steps0 + 1, MAX);
..................
return 0;
}

shell.c
,
,
, - . ,
? , ,
! - - .
, , ( ) while-.
16- ( l+1 r).
void shellSort(struct CElem m[], unsigned l, unsigned r)
{ static unsigned incs[16] = { 1391376,463792,198768,86961,33936,
13776,4592,1968,861,336,112,48,
21,7,3,1 };
unsigned i, j, k, h;
struct CElem v;
for (k = 0; k < 16; k++)
for (h = incs[k], i = l+h; i <= r; i++) {
v = m[i]; j = i;
while (j > h && m[j-h].key > v.key) {
m[j] = m[j-h];
j -= h;
}
m[j] = v;
}
}

shell2.c
?
. -, .
, ,
.
,
1, 3, 7, 15, 31, 63, 127, ..., 2k 1, ...
(n n ) [Papernov][Stasevic-1975].

1, 2, 3, 4, 6, 8, 9, 12, 16, ..., 2p3q, ... ,
, (n(log2 n)2) . ,
-, , ( [Pratt-1979]). (
[Knuth-3/1968])
1, 4, 13, 40, 121, ....,
k1 = 3 k + 1, s = 1, s = [log3 n] 1, .
, , :

3 -

206
1, 3, 7, 15, 31, ...

k1 = 2 k + 1, s = 1, s = [log2 n] 1, .
n1,2. ,
1,7.
(n(log2 n)2).
a :
, -, , < -.

3.1.4.
- ,
. -
3.1.4. , ( - !). - , ,
. , , . ,
- , .
,
xi1 xi , xi1 > xi,
( ). - ,
, , . . .
.
void bubbleSort1(struct CElem m[], unsigned n)
{ unsigned i, j;
for (i = 1; i < n; i++)
for (j = n-1; j >= i; j--)
if (m[j-1].key > m[j].key)
swap(m+j-1, m+j);
}

bubsort1.c


n(n1)/2
0


n(n1)/2
3.(n2n)/4


n(n1)/2
3.(n2n)/2

3.1.4. .
3.1.4.
. , , ,
, n(n1)/2. , .
, .
, . , ,
.
- , ,
, ,
. . , , -

3 -

207

, : . i,
, . ,
, ,
.
void bubbleSort2(struct CElem m[], unsigned n)
{ unsigned i, j, k;
for (i = n; i > 0; i = k)
for (k = j = 0; j < i; j++)
if (m[j].key > m[j+1].key) {
swap(m+j, m+j+1);
k = j;
}
}

bubsort2.c
a :
3.1.4.

3.1.5.
. - ,
.
: - ,
, ,
. ,
, .
. . ,
:
void shakerSort(struct CElem m[], unsigned n)
{ unsigned k = n, r = n-1;
unsigned l = 1, j;
do {
for (j = r; j >= l; j--)
if (m[j-1].key > m[j].key) {
swap(m+j-1,m+j);
k = j;
}
l = k + 1;
for (j = l; j <= r; j++)
if (m[j-1].key > m[j].key) {
swap(m+j-1,m+j);
k = j;
}
r = k - 1;
} while (l <= r);
}

shaker.c

3 -

208

- n1 ,
(n2).
, ,
. - .
a :
:
)
)
) .

3.1.6.
- , ,
, -
.
( !), .
... ?
, , , , ,
. :
. - , . ?
( 3.1.4.),
( 3.1.5.):
. ,
, ,
. , , ,
. ,

, ! ?
,
.., [n/2] .
- , -
.
, , x
: , - x, , -.
,
, ,
. , . (?)
q x , .. x = m[q].
m[l,l+1,...,r] partition() : (m[l,l+1,...,q])
(m[q+1,q+2,...,r]), q . , , .. partition() x , . -
.
- ( m[]
, : , .):

3 -

209

void quickSort(int l, int r)


{ int q;
if (l < r) {
q = partition(l,r);
quickSort(l,q);
quickSort(q+1,r);
}
}

, q. (
- - .) , m[q] x . q
: () ,
x, , - x.
: ?
- . :
unsigned partition(int l, int r)
{ int q, j, x;
q = l - 1; x = m[r].key;
for (j = l; j <= r; j++)
if (m[j].key <= x) {
q++;
swap(m+q,m+j);
}
if (q == r) /* <= x. 1. */
q--;
return q;
}

? x, . , - x,
- x. m[l,l+1,...,r] -, ,
- x. q. j r
, q . (: swap() - .)
i j,
.
, , . .
, - x.
( while-). -
, , .
, . . . i , j :
unsigned partition(int l, int r)
{ unsigned i, j, x;
i = l; j = r; x = m[l].key;
do {
while (x > m[i].key) i++;
while (x < m[j].key) j--;
if (i <= j) {
swap(m+i,m+j);
i++;

3 -

210

j--;
}
while (i <= j);
return j;
}

partition() quickSort() , ( ):
void quickSort(int l, int r)
{ int i,j,x;
i = l-1; x = m[r].key;
for (j = l; j <= r; j++)
if (m[j].key <= x) {
i++;
swap(m+i,m+j);
}
if (i == r) /* <= x. 1. */
i--;
if (l < i)
quickSort(l,i);
if ((i+1) < r)
/***/
quickSort(i+1,r); /***/
}

:
void quickSort(int l, int r)
{ int i, j, x;
i = l;
j = r;
x = m[r].key;
do {
while (x > m[i].key) i++;
while (x < m[j].key) j--;
if (i <= j) {
swap(m+i, m+j);
i++;
j--;
}
} while (j >= i);
if (j > l)
quickSort(l, j);
if (i < r)
/***/
quickSort(i, r); /***/
}

qsort.c
. , . To
, . .
, ,
. , /***/
l = i+1; ( ) l = i; ( ),
. ,
.

3 -

211

. ,
. ,

, . . ,
, , . ,
.
? ,
, ,
,
( x ):
void quickSort(void)
{ int i,j,l,r,s,x;
struct { int l, r; } stack[MAX];
stack[s = 0].l = 0;
stack[0].r = n-1;
for (;;) {
l = stack[s].l;
r = stack[s].r;
if (0 == s--)
break;
do {
i = l; j = r; x = m[(l+r)/2].key;
do {
while (m[i].key < x) i++;
while (m[j].key > x) j--;
if (i <= j) {
swap(m+i,m+j);
i++;
j--;
}
} while (i<=j);
if (i < r) {
/***/
stack[++s].l = i; /***/
stack[s].r := r; /***/
}
/***/
r = j;
/***/
} while (l < r);
}
}


. , , (log2 n) , . - ,
,
1, (n) . -,
: ,
. - , -
. ,
(log2 n). , /***/
(?):
/* - */
if (j - l < r i) {

3 -

212

/* */
if (i < r) {
stack[++s].l = i;
stack[s].r = r;
}
r = j;
}
else {
/* */
if (l < j)
stack[++s].l = l;
stack[s].r = j;
}
l = i;
}

, -
, - . -
, ,
log2 n .
n.log2 n. n/6.
(n/6).log2 n.
1/n, n, 2.ln 2 [Knuth-3/1968].
: x, ?
, , ( -).
: -
, -
, - , . . -
. (?) . , ,
. -,
3.2.3.,
.
. - , - ( 3.2. , !). (n.log2 n),
( 3.1.9.), -. ,
"" .
- , x,
. - ,
1, n2. [Knuth-3/1968][-1980]
. - ,
- . x

. , ,
- .
, ,
. ,
, , k ( k = 20) ,
- - ( 3.1.4.),
( 3.1.8.) ( 3.1.2.). - -

3 -

213

k .
, ,
, -
, .
: , .
. .
:
1. , .
2. , (log2 n).
3.
32 :
) ;
) 1 n;
) (
);
) .
4.
.
5. .
6. - ?
7. , - ,
, - .
8. - ( 3.1.6.):
) ;
) ;
) ;
) ;
) ;
) : ( 7.1.);
) , ( 3.2.3.).
9.
.
10. ,
(n.log2 n) - .
11. quickSort() int
unsigned.. ? ?
12. n , :
) (n.log2 n)
) (n2)

3.1.7.
( 3.1.4.),
. - ( 3.1.5. 3.1.6.),

, -
. , . . , , ,

3 -

214

. , , .
? ,
( 3.1.5.),
. 1991 . . Byte
,
, .
, , .
.
? 200 000 , ( ) 1,3.
1 .
, - 1,3, ,
, - .
, ,
,
, .
,
11. 9 10 11. ,
1,3, 1 :
964321
10 7 5 3 2 1
11 8 6 4 3 2 1
1.
8% ,
15-20%.
( 3.1.3.)
. , . ( 3.1.2.) ,
( 3.1.4.).
.
. 1,7,
1,3. , (n.(log2 n)2),
(n.log2 n) , - .
- .
:
void combSort(struct CElem m[], unsigned n)
{ unsigned s, i, j, gap = n;
do {
s = 0;
gap = (unsigned) (gap/1.3);
if (gap < 1)
gap = 1;
for (i = 0; i < n-gap; i++) {
j = i + gap;
if (m[i].key > m[j].key) {
swap(m+i, m+j);
s++;
}
}
} while (s != 0 || gap > 1);
}

3 -

215

combsort.c

.
, . :
gap = (long)(gap/1.3);

:
gap = (long)(gap*0.76923076923);

:
gap = gap*8 / 11;

, , :
gap = gap*6 >> 3.

, . 1,279604943109628
1,3. , , . ( ) 4
:
11, 13, 17, 23, 29, 37, 47, 61, 79, 103, 131, 167, 216, 277, 353, 449, 577, 739, 947, 1213, 1553, 1987,
2543, 3259, 4166, 5333, 6829, 8741, 11177, 14310, 18313, 23431, 29989, 38371, 49103, 62827, 80407,
102881, 131648, 168463, 215573, 275840, 352973, 451669, 577957, 739560, 946346, 1210949, 1549547,
1982809, 2537202, 3246624, 2147483647
:
1. , (n.log2 n)
, - .
2. ( 3.1.3.)
.

3.1.8.
(n2) ,
. ,
.
.
..

(, -
, ?), ,
.
void straightSelection(struct CElem m[], unsigned n)
{ unsigned i, j;
for (i = 0; i < n-1; i++)
for (j = i+1; j <= n; j++)
if (m[i].key > m[j].key)
swap(m+i, m+j);
}

selsort.c

3 -

216

: , , , j-
m[j] , x.
void straightSelection(struct CElem m[], unsigned n)
{ unsigned i, j, ind;
struct CElem x;
for (i = 0; i < n - 1; i++)
for (x = m[ind = i], j = i + 1; j < n; j++)
if (m[j].key < x.key) {
x = m[ind = j];
m[ind] = m[i];
m[i] = x;
}
}

selsort2.c


n(n1)/2
3(n1)


n(n1)/2
nln n


n(n1)/2
[n2/4]+3(n1)

. 3.1.8. .
n(n1)/2 , 3.1.8.
,
- .
:
1. , .
2. .
3. 3.1.8.

3.1.9.
( 3.1.8.) -,
( 3.1.4.) ( 3.1.2.). , i n i , .
() n n1 . ,
, ,
n1 .
, , , n1 , - ,
. , n2
. , i- ni
. ? , . ,
,
,
. , -

3 -

217

, - , . .
- - ( 3.1.1.),
.
, ( [Knuth-3/1968], [, , -1980]),
. x1 :
x2, x3 : x4, ..., xn1 : xn. ..
. i-
( , n 2,
?), , . , :
n/2 ,
n/4 (. . 4 ) ..
, . . n1 . , ()
,
.
lg2n, ", . .
, lg2n1 n2,
. n1+(n1)(log2 n1)
.
, .
, .
, -
:
( 3.1.5.) -
( 3.1.4.), .
, ,
. , ,
( 2.4.), ,
,
. , , ,
.
,
2n1. ,
, ,
. .
.
3.1.
h, :
1) h h1;
2) - ;
3) h .
, ,
n- ,
.
:
. hl, hl+1, ..., hr (1 l r
n), hi h2i hi h2i+1, i = l, l+1 ..., r/2.

3 -

218

, h1 h1, h2, ..., hn - . (?)


, - , - . , l = 1 . , h2i h2i+1
hi.
,
buildHeap(), k restoreHeap(k),
. , n
, h1 (- ) hn,
: .
, . h1, h2, ..., hn1, -.
(n1)- ,
. n1 ( n- , n , ?).
:
buildHeap();
for (i = n; i >= 2; i--) {
swap(m+1, m+i);
restoreHeap(i-1)
}

? , n .
hn/2+1, hn/2+2, ..., hn ,
i j j = 2i j = 2i + 1. , ( !) ( ) . . x
. , x . hn/2, hn/2+1, ..., hn .
, . n
hn/2+1, hn/2+2, ..., hn. ,
, / .
, x
, . . x
, x .. x , , .
, , x -
, . x , ,
.
, ,
.
sift():
/* */
void sift(struct CElem m[], unsigned l, unsigned r)
{ unsigned i = l,
j = i + i;
struct CElem x = m[i];
while (j <= r) {
if (j < r && m[j].key < m[j+1].key)
j++;
if (x.key >= m[j].key)

3 -

219

break;
m[i] = m[j];
i = j;
j <<= 1; /* j *= 2; */
}
m[i] = x;
}

heapsort.c
( buildHeap()) :
for (k = n/2 + 1; k > 1; k--)
sift(m,k-1,n);

,
( restoreHeap()), :
for (k = n; k > 1; k--) {
swap(m+1,m+k);
sift(m,1,k-1);
}

:
void heapSort(struct CElem m[], unsigned n) /* */
{ unsigned k;
/* 1. */
for (k = n/2 + 1; k > 1; k--)
sift(m,k-1,n);
/* 2. */
for (k = n; k > 1; k--) {
swap(m+1,m+k);
sift(m,1,k-1);
}
}

heapsort.c
:
1. , ,
2, .
2. , - .
3. , . () .
?
4. .

3.1.10.


(. . ,
> (), < () = (). - (
, , 3.1.2., 3.1.4 3.1.8.) (n2)

3 -

220

, - (n.log2 n) ( ,
3.1.6.) - ( : 3.1.9.,
: 3.1.7. , 7.3.). ,
,
. . . -
(n.log2 n). ?
:
.
(n.log2 n).
.
, 3.1.1.
n! .
.
, <.
=, , , <, > , , , . .
, .
. . , ,
.
- , -
, , . .
. n ,
n! , . .
.
h (. .
). :
n! 2h
:
h log2 (n!)
n!, n! > (n/e)n,
:
h log2 (n!) log2 (n/e)n = n.log2 n n.log2 e,
, h (n.log2 n). . . ,
, (n.log2n).
, ,
. , - (
/ ) - ,
3.2.
:
,
.

3 -

221

3.2.
, , ( ) .
( 2.3.) ( 2.5.).
/ /
.

3.2.1.
,
, . ,
f (
M, n):
1) f [a, b], m = b a +
1 . [a, b] f,
f [a, b].
2) f , . . x1, x2 M x1 x2 f(x1) f(x2) (. . )
struct CElem,
unsigned, ,
MAX_VALUE. (, MAX_VALUE m) [0, MAX_VALUE).
, .
0 set[] ( char,
),
1 .
set[].
, m[] ,
. .
void setSort(unsigned m[], unsigned n)
{ char set[MAX_VALUE];
unsigned i,j;
/* 0. */
for (i = 0; i < MAX_VALUE; i++)
set[i] = 0;
/* 1. */
for (j = 0; j < n; j++) {
assert(m[j] >= 0 && m[j] < MAX_VALUE);
assert(0 == set[m[j]]);
set[m[j]] = 1;
}
/* 2. */
for (i = j = 0; i < MAX_VALUE; i++)
if (set[i])
m[j++] = i;
assert(j == n);
}

3 -

222

set_sort.c
(m+n) n, m,
n. , "":

( , ),
(m). , . ,
( 3.1.6.), , -
( ). : (n), a (m), m > n m >> n (.. m -
n).
, .
.
struct CElem, .
(m+n), m
[a, b].
[a, b] m[],
. - .
m[]:
struct CSetEl {
char found;
unsigned index;
} m[MAX];

found , m[] . ,
m[] :
unsigned m[MAX];

, , - 0,
- unsigned.
( DOS 65 535, Windows 4 294 967 295). 1
: (unsigned)(-1).
, ,
m[],
, . assert()-, , .
#define NO_INDEX (unsigned)(-1)
/* */
void setSort(struct CElem m[], unsigned n)
{ unsigned indSet[MAX_VALUE]; /* */
unsigned i,j;
/* 0. */
for (i = 0; i < MAX_VALUE; i++)
indSet[i] = NO_INDEX;
/* 1. */
for (j = 0; j < n; j++) {
assert(m[j].key >= 0 && m[j].key < MAX_VALUE);
assert(NO_INDEX == indSet[m[j].key]);

3 -

223

indSet[m[j].key] = j;
}
/* 2. */
for (i = j = 0; i < MAX_VALUE; i++)
if (NO_INDEX != indSet[i])
do4Elem(m[indSet[i]]);
}

setsort2.c
. , m[]. do4Elem() . , . , .
m[],
. m[].
, m[]. , ,
struct CElem [a, b]. ,
, ,
(m), (...) - .
:
, .

3.2.2.
.
, . . . , ,
k .
,
. cnt[], cnt[i]
i. cnt[],
m[] [a, b].
cnt[], cnt[x]
x, x [a, b].
void countSort(unsigned m[], unsigned n) /* */
{ unsigned char cnt[MAX_VALUE];
unsigned i,j;
/* 0. */
for (i = 0; i < MAX_VALUE; i++)
cnt[i] = 0;
/* 1. */
for (j = 0; j < n; j++) {
assert(m[j] >= 0 && m[j] < MAX_VALUE);
cnt[m[j]]++;
}
/* 2. */
for (i = j = 0; i < MAX_VALUE; i++)

3 -

224

while (cnt[i]--)
m[j++] = i;
assert(j == n);
}

count_s.c
, k , k. T
:

[a, b], [a, b]


f, f [a, b].
[a, b] k ;
, .

. . .

x [a, b] M, .
: x
x.

, : .
k, -
k . k p
.
- ,
M. ,
, ( ).
, , M. ,
( -,
: ). (m+n).
#include
#include
#include
#include
#include
#define
#define
#define
#define

<assert.h>
<stdlib.h>
<stdio.h>
<string.h>
<time.h>

MAX 100
FACTOR 5
MAX_VALUE (MAX*FACTOR)
TEST_LOOP_CNT 100

struct CElem {
int key;
/* */
};
struct CList {
struct CElem data;
struct CList *next;
};
void init(struct CElem m[], unsigned n)

3 -

225

{ unsigned i;
srand(time(NULL));
for (i = 0; i < n; i++)
m[i].key = rand() % MAX_VALUE;
}
void countSort(struct CElem m[], unsigned n)
{ /* . - ! */
unsigned i,j;
struct CList *lst[MAX_VALUE], *p;
/* 0. */
for (i = 0; i < MAX_VALUE; i++)
lst[i] = NULL;
/* 1. */
for (j = 0; j < n; j++) {
/* 1.1. */
assert(m[j].key >= 0 && m[j].key < MAX_VALUE);
/* 1.2. */
p = (struct CList *) malloc(sizeof(struct CList));
p->data = m[j];
p->next = lst[m[j].key];
lst[m[j].key] = p;
}
/* 2. */
for (i = j = 0; i < MAX_VALUE; i++)
while (NULL != (p = lst[i])) {
m[j++] = lst[i]->data;
lst[i] = lst[i]->next;
free(p);
}
}
void print(struct CElem m[], unsigned n)
{ unsigned i;
for (i = 0; i < n; i++)
printf("%8d", m[i].key);
}
int main(void) {
struct CElem m[MAX];
init(m, MAX);
printf(" :\n");
print(m,MAX);
countSort(m, MAX);
printf(" :\n");
print(m,MAX);
return 0;
}

count_s2.c
:
.

3 -

226

3.2.3.
, ( 3.2.2.) ( 3.2.1.)
. ,
m. , m
.
, ,
.
, (n), ,
(m). (m+n). , m n. ? , m > n
m.
-, n.
, m = n3, (n3), . . -
! m = n7?
,
. ( , ) , ( 3.2.4.).

. ,
. . , .
, .

. -.
, .. - . , (?). - . , ,
. , .
, , , ,
- ,
. ,
. ,
( ), .
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MAX 100
struct CElem {
int key;
/* .............

............. */
};

3 -

struct CList {
struct CElem data;
struct CList *next;
};

struct CList* init(unsigned n) /* */


{ struct CList *head, *p;
unsigned i;
srand(time(NULL));
for (head = NULL, i = 0; i < n; i++) {
p = (struct CList *) malloc(sizeof(struct CList));
p->data.key = rand();
assert(p->data.key);
p->next = head;
head = p;
}
return head;
}
struct CList *bitSort(struct CList *head)
{ struct CList *zeroEnd, *oneEnd, *zero, *one;
unsigned maxBit, bitPow2;
/* 0. */
maxBit = 1 << (8*sizeof(head->data.key)-1);
/* 1. */
zero = (struct CList *) malloc(sizeof(struct CList));
one = (struct CList *) malloc(sizeof(struct CList));
/* 2. */
for (bitPow2 = 1; bitPow2 < maxBit; bitPow2 <<= 1) {
/* 2.1. */
for (zeroEnd = zero, oneEnd = one; NULL != head; head = head->next)
if (!(head->data.key & bitPow2)) {
zeroEnd->next = head;
zeroEnd = zeroEnd->next;
}
else {
oneEnd->next = head;
oneEnd = oneEnd->next;
}
/* 2.2. */
oneEnd->next = NULL;
zeroEnd->next = one->next;
head = zero->next;
}
/* 3. */
free(zero);
free(one);
return head;
}

227

3 -

228

void print(struct CList *head)


{ for (; NULL != head; head = head->next)
printf("%8d", head->data.key);
printf("\n");
}
void check(struct CList *head)
{ if (NULL == head)
return;
for (; NULL != head->next; head = head->next)
assert(head->data.key <= head->next->data.key);
}
void clear(struct CList *head)
{ struct CList *p = head;
while (NULL != head) {
head = (p = head)->next;
free(p);
}
}
int main(void) {
struct CList *head;
head = init(MAX);
printf(" :\n");
print(head);
head = bitSort(head);
printf(" :\n");
print(head);
check(head);
clear(head);
return 0;
}

bitsort.c
. - . n- , .
, , ,
. .. , n/2 ( - ). [-1995] [ComputerNews-1994a] [TopTeam-1997]
, C.n, C . , .
-
-. , ,
: - 0, - 1,
, . - .

, 2b, b = 0,1,2,... . 2b ,
, . ,
i = j . (?)
.

3 -

229

struct CElem m[MAX];


.................
void bitSort2(int l, int r, unsigned bitMask)
{ int i,j;
if (r > l && bitMask > 0) {
i = l; j = r;
while (j != i) {
while (!(m[i].key & bitMask) && i < j) i++;
while ((m[j].key & bitMask) && j > i) j--;
swap(&m[i], &m[j]);
}
if (!(m[r].key & bitMask)) j++;
bitSort2(l,j-1,bitMask >> 1);
bitSort2(j,r,bitMask >> 1);
}
}
.................
int main(void) {
.................
bitSort2(0,MAX-1,1 << 8*sizeof(m[0].key) - 1);
.................
return 0;
}

bitsort2.c
: , - ,
.
, . . ,
065535, 01000. ,
, 6 ,
: 0
.
:
1. , .
2. ,
, , ,
.
3. .

3.2.4.
- . , . , , ? 10?
16? 256? ,
C, . . .

3 -

230

.
s .
, s.
. . .
, s- , . .
s- .
. , s = 2 .
. ,
- s n ( n < s). 2 -
.
16 8
. 16- , , .
, ,
, .
. , .
.
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MAX
100
#define BASE
16 /* */
#define POW2
4 /* 16 = 1 << 4 */
#define DIG_CNT 8 /* */
struct CElem {
int key;
/* */
};
struct CList {
struct CElem data;
struct CList *next;
};
struct CList *init(unsigned n) /* */
{ struct CList *head, *p;
unsigned i;
srand(time(NULL));
for (head = NULL, i = 0; i < n; i++) {
p = (struct CList *) malloc(sizeof(struct CList));
p->data.key = rand();
assert(p->data.key);
p->next = head;
head = p;
}
return head;
}
struct CList *radixSort(struct CList *head)
{ struct { struct CList *st, *en; } mod[BASE];
unsigned i, dig, mask, shrM;

3 -

/* 1. */
for (i = 0; i < BASE; i++)
mod[i].st = (struct CList *) malloc(sizeof(struct CList));
/* 2. */
mask = BASE-1; shrM = 0;
for (dig = 1; dig <= DIG_CNT; dig++) {
/* 2.1. */
for (i = 0; i < BASE; i++)
mod[i].en = mod[i].st;
/* 2.2. */
while (NULL != head) {
/* 2.2.1. i- BASE- */
i = (head->data.key & mask) >> shrM;
/* 2.2.2. */
mod[i].en->next = head;
mod[i].en = mod[i].en->next;
head = head->next;
}
/* 2.3. */
mod[BASE-1].en->next = NULL;
for (i = BASE - 1; i > 0; i--)
mod[i-1].en->next = mod[i].st->next;
head = mod[0].st->next;
/* 2.4. */
shrM += POW2; mask <<= POW2;
}
/* 3. */
for (i = 0; i < BASE; i++)
free(mod[i].st);
return head;
}
void print(struct CList *head)
{ for (; NULL != head; head = head->next)
printf("%8d", head->data.key);
printf("\n");
}
void clear(struct CList *head)
{ struct CList *p = head;
while (NULL != head) {
head = (p = head) ->next;
free(p);
}
}
int main(void) {
struct CList *head;
head = init(MAX);
printf(" :\n");
print(head);
head = radixSort(head);

231

3 -

232

printf(" :\n");
print(head);
clear(head);
return 0;
}

radsort.c
,
. , , .
. , : , , , , , .
d1 = 60, d2 = 60, d3 = 24, d4 = 7, d5 = 52.
-, .
60
, 60 , ,
24 , ..
a :
.

3.2.5.
. -
( 3.2.2.) ( 3.2.1.).

( M,
n):
1) f [a, b], m
, m = b a + 1. [a, b] f,
f [a, b].
2) f , . . x1, x2 M, x1 x2 f(x1) f(x2) (. . )
:
3) f: M M , . . s M x , f(x) = s
M n, .. |M| = n. S {1, 2, ..., n}.
:
1) f : S S
2) f (. . )
f M . , M ,
.
. i i- . ,
i j, j = m[i], i j, i- j- ,
j j- . i-
i, (i+1)- m[].
: m[i]. ,
i i- . (?)

3 -

233

4375612. i = 1 m[1] m[m[1]] 1


1 ( , , .):
4375612
5374612
6374512
1374562

1 . 2:
1374562
1734562
1234567

2 .
, .
[-1998].
,
. , n.
2n. ,
- :
. ,
, .
void permSort(struct CElem m[], unsigned n)
{ unsigned i;
for (i = 0; i < n; i++)
while (m[i].key != (int)i)
swap(&m[i],&m[m[i].key]);
}

permsort.c
:
, i (1 i n)
m[i] m[m[i]] m[i] i.

3.3.
- ,
() .

. , ,
, .
. ,

- .
,
. ,
,
. ,
-
,
. :

3 -

234

- .
,
, ,
,
. , ;))
, ,
, . ,
. , (, ) .
,
(),
.
.
, . ()
(- ) . . . .
. ,
. - , , . , ( )
.
, : 10
, 10000 . ,
-
, , -
- .
, , . ,
, , .
, ,
. :
. , ,
.
.
- (
7.4.). , , .
x y, min(x,y), max(x,y). ,
,
, . . . ,
, , ,
. , ,
.
().
n n , <a1, a2, , an>
n- <b1, b2, , bn>, , , . .
n- . a1, a2, ,

3 -

235

an A, , . .
x y A : x < y, x = y
x > y ( ). , A
. - , A . ,
, , , . , , . (?)
n ,
. ,
, - , ,
-. , , 1.
,
.
, , .
. , 1,
, 0,
, .
, ,
, .

. 0.
d(x) d(y) ,
max(d(x), d(y)) + 1. , .
, <a1, a2, , an>
: b1 b2 bn.
, , .

3.3.1.
. ( ) ()
0 1,
, .
..
, (
) . , 2n- 0 1
n, n, , . ,
, :
2n , 30 . ,
.
1. f ,
f(x) f(y). f(min(x,y))
f(max(x,y)) .
: , f , min(f(x),f(y)) = f(min(x,y))
max(f(x),f(y)) = f(max(x,y)), .

3 -

236

2. f . ,
a = <a1, a2, , an> b = <b1, b2, , bn>.
f(a) = <f(a1), f(a2), , f(an)> f(b) = <f(b1), f(b2), , f(bn)>.
: , f , . .
x < y f(x) f(y). ,
, - ,
, : y x,
f(y) f(x). d :
1) : d = 0. x y . , f(x)
f(y) .
2) : , ,
- d (d > 0), x y, f(x)
f(y).
3) : d
x1 x2 .
y1 = min(x1,x2) y2 = max(x1,x2) . , , f(x1), f(x2)
f(y1) f(y2) . f
. , 1 min(f(y1), f(y2))
max(f(y1), f(y2)) .
f . 2
.
.
( ): -
2 . : .
, 0
1 , <a1, a2, , an>
A, .
ai aj (ai < aj) , aj
ai. f :

0, x ai
f (x )
1, x ai
, .
aj ai 2 , f(aj) f(ai). , f f(aj) = 1 f(ai) = 0. <f(a1), f(a2), , f(an)>, 0 1.
, 0 1.

3.3.2.
- - . - ,
. ,
. , , : ,
. : <1, 7, 9, 11, 27, 5, 4, 3, 3, 1> <37, 20, 17, 16, 10, 10, 10, 18,
25, 47>. , ,
. , 0 1, 0i1j0k 1i0j1k , i, j, k

3 -

237

0. , - 0 1.

3.3.3.
- - . , ( 3.1.6.),
. n
, n/2. - , . . - .
, 0 () 1
(), " ". 1
(i,n/2+i) i = 1, 2, , n/2.

3.3.4.
, n/2 . . n/4 ,
.. n
2,
1. ,
. (?)
.
1 ( ), ( ), , log2 n.
0 1 (log2 n).
, , .
. 0 1.

3.3.5.
. ,
, . ,

, .
, ,
. , 1
. -
. 1 + log2 n. -
, , , . .
.
, (i,n/2+i), (i,ni+1), i = 1, 2, , n/2.
,
- .
. ,
log2 n.

3 -

238

3.3.6.
, :
.
( 7.4.)
.
- , n 2.
. , ,
n/2.
log2 n, . ? , 4 l1, l2, l3, l4
n/4 . , l1 l2
n/2 log2 (n/2). l3 l4,
, .
n/2.
l1, l2, l3, l4? . ,
n/8,
log2 (n/8) ..
, .
.
. D(n) , n- , D(n/2) , (n/2)- (,
, ), log2 n . :

n 1
0

D(n) D n log n n 2 k , k 1

2

2
( 1.4.10.) :

D(n) log 22 n

3.3.7.
- , ,
. ,
, . 3.3.7. ,
( 3.1.2.).

3.3.7. .

3 -

239

, .
. , ,
. , .

3.3.8. -
- 1960 . :
n- <a1, a2, , an> <an+1, an+2, ,
a2n>, (n 2).
. (<a1, a3, , an1> <an+1, an+3, , a2n
1>) (<a 2, a 4, , a n > <a n+2, a n+4, , a 2n >) .
, n/2 ,
a2i1 a2i i = 1, 2, , n. (log2 n).

3.3.9. -
- , log 22 n . n
. i (i = 2, 3, ..., n1), d
(d = 1,2, ,n). i j = i+(1)i+d, 1 j
n d. . . : (
3.3.9.)

d = 1, 2, ..., n :
1) d , 2i1 2i, i = 1, 2, ..., [n/2].
2) d , 2i 2i+1, i = 1, 2, ..., [(n1)/2].

3.3.9. - .

3.3.10.
, , .
. , , ,
(). n <1, 2, , n>. , , , n
. , n! ,
. ,
.

3 -

240

,
, 1954 . - 1960 .
- , .
, .
- log 22 n .
1983 . , ,
log 2 n , n log 2 n .
, ,
, (...).

:
1. , 3.3.4. ( 3.3.4.).
2. , n (n2) ( 3.3.7.).
3.
n ( 3.3.7.), :
) ( 3.1.2.);
) ( 3.1.4.).
4. , ,
n , (n,n
1,,1).
5. , n > 2 n
, ( 3.3.10.).

3.4.
3.4.1.
3.1.
, - ( 3.1.1.).
3.2.
, , , ( 3.1.2.).
3.3.
( 3.1.2.).
3.4.
3.1.2.
3.5.
, -, , < - ( 3.1.3.).
3.6.
3.1.4.
3.7.
( 3.1.4.):

3 -

241

)
)
) ( 3.1.5.).
3.8.
, ( 3.1.6.)
.
3.9.
, ( 3.1.6.)
(log2 n).
3.10.
(
3.1.6.) 32 :
) ;
) 1 n;
) (
);
) .
3.11.
-
( 3.1.6.):
) ;
) ;
) ;
) ;
) ;
) : ( 7.1.);
) , ( 3.2.3.).
3.12.

.
3.13.
( 3.1.6.).
3.14.
( 3.1.6.)
- ?
3.15.
, - , ( 3.1.6.), - .
3.16.
( 3.1.6.),
(n.log2 n) - .
3.17.
quickSort() int
unsigned 3.1.6.. ? ?
3.18.

3 -

242

n ,
( 3.1.6.) :
) (n.log2 n)
) (n2)
3.19.
, ( 3.1.7.) (n.log2 n)
, - .
3.20.
( 3.1.3.)
( 3.1.7.).
3.21.
, ( 3.1.8.).
3.22.
(
3.1.8.).
3.23.
3.1.8.
3.24.
, ,
2, ( 3.1.9.).
3.25.
, - ( 3.1.9.).
3.26.
, . () .
( 3.1.9.)?
3.27.
( 3.1.9.).
3.28.
,
( 3.2.).
3.29.
( 3.2.1.)
, .
3.30.
( 3.2.2.).
3.31.
, i (1 i n)
m[i] m[m[i]] m[i] i (
3.2.5.).
3.32.

3 -

243

, 3.3.4. ( 3.3.4.).
3.33.
, ( 3.2.3.) .
3.34.
( 3.2.3.), , , , .
3.35.
(
3.2.3.).
3.36.
( 3.2.3.) (
3.2.4.).
3.37.
, n (n2) ( 3.3.7.).
3.38.

n ( 3.3.7.), :
) ( 3.1.2.);
) ( 3.1.4.).
3.39.
, ,
n , (n,n
1,,1).
3.40.
, n > 2 n
, ( 3.3.10.).

3.4.2.
3.41. .
: ( 3.1.2.),
( 3.1.4.) ( 3.1.8.).
:
) : 10; 20; 50; 100; 1000; 10000;
) : ; ; ;
.
3.42. .
, , , n1
.
3.43. .

3 -

244

( 3.1.6.),
( 3.1.7.) ( 3.1.9.).
3.44. .
(,
: 3.1.2., 3.1.4. 3.1.8.) -
( 3.1.6.). .
?
3.45.- - .
- - .
3.46. .
, , ?
3.47. .
?
3.48. .
, , -
:
) ;
) .
3.49. .
, ,
. ,
.
3.50. .
A = (aij). , . ?

I have an existentialist map of the world.


It has "You are here" written all over it.
~ Unix Fortune
, 3, . ,
. , . ,
, . , - .
, - . ,
: , ,
, , , , " ", . , . ,
. ,
, .
, . ,
. ,
( ), ( ), (
), (
), ( ),
( ) .
- , (
).
, - ,
. -
, :

;
;
, , , . .
;
() ;
;
.

. , , , . , , :
, .
,
. ,
, - . , ,

4 -

246

-, (log2n) , - . , .
,
(n.log2 n). (n.log2 n). , ,
. .
:

. ,
. ( , 2),
, struct CElem,
.
, . - ,
. , , .
, ? , .
. , - , . ,
, .
, . , , , , . ,
. - , .

.

4.1.
- - . , .

. , .
seqSearch(). , :
#include <stdio.h>
#include <stdlib.h>
#define MAX 100

4 -

247

#define DataType int


struct CElem {
int key;
DataType data;
/* ... */
} m[MAX + 1]; /* */
unsigned n;
/* */
void seqInit(void) { n = 0; }

/* */

unsigned seqSearch(int key)


/* */
{ unsigned x;
m[0].key = key; /* */
for (x = n + 1; key != m[--x].key; ) ;
return x;
}
void seqInsert(int key, DataType data) /* */
{ m[++n].key = key;
m[n].data = data;
}
void seqPrint(void)
/* */
{ unsigned i;
char buf[9];
for (i = 1; i <= n; i++) {
sprintf(buf, "%d|%d", m[i].key, m[i].data);
printf("%8s", buf);
}
}
void performSearchTest(void)
{ unsigned ind, elem2Search;
for (elem2Search = 0; elem2Search < 2*MAX; elem2Search++) {
printf(" %u.\n", elem2Search);
if (0 == (ind = seqSearch(elem2Search)))
printf("%s"," !\n");
else
printf("% ! . : %d\n", m[ind].data);
}
}
int main(void) {
unsigned ind;
seqInit();
for (ind = 0; ind < MAX; ind++)
seqInsert(rand() % (MAX*2), ind);
printf(" : \n");
seqPrint();
printf("\n:\n");
performSearchTest();
return 0;
}

seq_arr.c
, - ,
data. ,

4 -

248

struct CElem
, .
. , , .
-, : , (
). .
- ? ,
- . n+1 , . , ,
(n+1)/2 (?). ,
.
:
, (n+1)/2.

4.1.1.
, -, - - . , . ,
. , ,
, . ,
, .
. -
, , .
? , ,
- , - .
(n+1)/2, n+1 .
, . - , . . n+1 .
, , , -
, , . , "" ,
, .
,
:
struct CElem {
int key;
DataType data;
struct CElem *next;
/* ... */
} *head;
void listInit(void)
/* */
{ head = (struct CElem *) malloc(sizeof *head);
head->next = NULL;
}
void listInsert(int key, DataType data) /* */

4 -

249

{ struct CElem *p, *q, *r;


q = (struct CElem *) malloc(sizeof *head),
r = (p = head)->next;
while (r != NULL && r->key < key) {
p = r;
r = r->next;
}
q->key = key;
q->data = data;
q->next = r;
p->next = q;
}
struct CElem *listSearch(int key) /* */
{ struct CElem *q;
for (q = head->next; q != NULL && q->key < key; q = q->next) ;
if (NULL == q || key != q->key)
return NULL;
else
return q;
}
void listPrint(void)
/* */
{ struct CElem *q;
char buf[9];
for (q = head->next; q != NULL; q = q->next) {
sprintf(buf, "%d|%d", q->key, q->data);
printf("%8s", buf);
}
}

seq_list
:
.
.

4.1.2.
,
, , - , . . , , .
, ,
:
. . , - . ,
.
, . . , . , n, -
,
[-1980].

4 -

250

- ,
n .
, - -. , - .
. ,
. , , .
, , .
, - , -
. -
:
, . (
10.5.)
void listInsert(int key, DataType data) /* */
{ struct CElem *q = (struct CElem *) malloc(sizeof *head);
q->key = key; q->data = data;
q->next = head; head = q;
}
/* */
struct CElem *listSearch(int key)
{ struct CElem *q, *p = head;
if (NULL == head)
return NULL;
if (head->key == key) return head;
for (q = head->next; q != NULL; )
if (q->key != key) {
p = q;
q = q->next;
}
else {
p->next = q->next;
q->next = head;
return (head = q);
}
return NULL;
}

reorder.c
:
1. ,
. -.
2.
( 10.5.).
3.
. .
4. -, -
:
) ( 4.1.)
) ( 4.1.1.)
) ( 4.1.2.)

4 -

251

4.2. .

. -

. , . k
-
, (k+1)- , (2k+1)- , (3k+1)- ,... . .
m[1].key, m[k+1].key, m[2k+1].key,... , - x, .
- ( ).
, , , , - x. , . ,
,
.
, . ,
. ,
k = 1.
- ,
m[1].key. ? ,
, , m[n].key: . , - m[k].key.
(?) k = 1 .
k - ?
, [m[i*k+1].key;
m[(i+1)*k].key], . , - k .
- , , [n/k] , ,
. , n, k, k1.
, - k [n/k] + k
1 . :
unsigned seqSearch(unsigned l, unsigned r, int key)
{ while (l <= r)
if (m[l++].key == key)
return l-1;
return NOT_FOUND;
}
unsigned jmpSearch(int key, unsigned step)
{ unsigned ind;
for (ind = 0; ind < n && m[ind].key < key; ind += step) ;
return seqSearch(ind + 1 < step ? 0 : ind + 1 - step,
n < ind ? n : ind, key);
}

jumpsear.c
: , n k , ? 4.2. , n k:

4 -

252

n\k
1
2
3
4
5
6
7
8

1
1
2
3
4
5
6
7
8

2
2
3
3
4
4
5

3
3
3
4
4
4

4
4
4
4
5

5
5
5
5

6
6
6

7
7

4.2. n k.
, - k n/2, . .
. -
k - n,
n k f(k) :
f(k) = [n/k] + k 1.
( ),
k = n . f(k) 2 n + 1. .
, : n n .
? , . , - f(k), , . : , l (1 < l < k)
? , k n ,
, .
k ,
l , n/(k.l)
. , ,
, k = l = n/(k.l), n = k3. 3 3 n . n 12 , 3 3 n < 2 n , . .
[Gregory,Rawlins-1997].
, , . . ? ,
, .
( !)
, - .
:
1. k l.
k l n.
2. , - n
n .

4.3.
. -

4 -

253

,
7. -,
- . . .
? ,
.
. - , a - -.
,
, . , .
? x ,
. x ( .). .
x - ,
. , : ,
- , - x. , x - , . .
. , . , . ,
. , , , . , , , , ( ) . ,
( 1).
, ( binSearch(__,0,n-1)):
unsigned binSearch(int key, int l, int r)
{ int mid;
if (l > r)
return NOT_FOUND;
mid = (l + r) / 2;
if (key < m[mid].key)
return binSearch(key,l,mid-1);
else if (key > m[mid].key)
return binSearch(key,mid+1,r);
else
return mid;
}

binsear0.c
- .
. , :
unsigned binSearch(int key)
{ int l = 0, r = n-1, mid;
while (l <= r) {
mid = (l + r) / 2;
if (key < m[mid].key)
r = mid - 1;

4 -

254

else if (key > m[mid].key)


l = mid + 1;
else
return mid;
}
return NOT_FOUND;
}

binsear1.c
l r, . mid . , value 1, .
,
log2 n + 1 .
, [-1980].
.
log2 n + 1 . ,
. - . -
l r, .
, offset = r-l r.
offset . ,
,
. .
-
, , . ,
. ,
1000, : (1, 2,
..., 512) (489, 490, ..., 1000).
, 512, 2, n = 1000. 489, 490, , 512 . ,
. , .
(, .)
unsigned getMaxPower2(unsigned k)
{ unsigned pow2;
for (pow2 = 1; pow2 <= k; pow2 <<= 1) ;
return pow2 >> 1;
}
unsigned binSearch(int key)
{ unsigned i, l, ind;
i = getMaxPower2(n);
l = m[i].key >= key ? 0 : n - i + 1;
while (i > 0) {
i = i >> 1;
ind = l + i;
if (m[ind].key == key)
return ind;
else if (m[ind].key < key)
l = ind;
}
return NOT_FOUND;
}

4 -

255

binsear2.c
.

.
:
unsigned binSearch(int key)
{ unsigned i, l;
i = getMaxPower2(n);
l = m[i].key >= key ? 0 : n - i + 1;
while (i > 1) {
i = i >> 1;
if (m[l+i].key < key)
l += i;
}
return (l < MAX && m[++l].key == key ? l : NOT_FOUND);
}

binsear3.c
- . , ,
, n ,
.
, .
.
4,5 ( [Bentley-1986]).
, ,
,
.
:
unsigned binSearch(int key)
{ unsigned l = 0;
if (m[512].key
< key) l = 1000-512+1;
if (m[l+256].key < key) l += 256;
if (m[l+128].key < key) l += 128;
if (m[l+ 64].key < key) l += 64;
if (m[l+ 32].key < key) l += 32;
if (m[l+ 16].key < key) l += 16;
if (m[l+ 8].key < key) l +=
8;
if (m[l+ 4].key < key) l +=
4;
if (m[l+ 2].key < key) l +=
2;
if (m[l+ 1].key < key) l +=
1;
return (l < 1000 && m[++l].key == key ? l : NOT_FOUND);
}

binsear4.c
, . , , . . , , , ,
. , .
, - (n+1)- ,
- .

4 -

256

n/2, - n (n
).
- , . , , .
, , .
, . , .
- , .
, ,
. , ,
, . . - , , , .
.
:
1. n 10, 100, 1000 ( 4.1.)?
2. .

4.4.
, , . -
,
. ,
, . ,
.

mid = (l + r) / 2;


mid = (l + r) >> 1;


, 2
, . . .
. ,
p : p
(
).
, ,
(
). .
, ( 1.2.2.):
F0 = 0, F1 = 1, Fn = Fn1 + Fn2, n 2
,
- .
, . , n-
, n = Fk 1. x m[Fk1].key.
. x < m[Fk1].key

4 -

257

1, 2, ..., Fk11. x > m[Fk1].key


Fk1+1, Fk1+2, ..., n = Fk . ,
Fk11, Fk21.
( [Horowitz-1977]).
(l 0 , Fk + l = n + 1 Fk+1 > n+1):
unsigned fib[MAX]; /* , n */
unsigned findFib(unsigned n)
{ unsigned k;
fib[0] = 0;
fib[1] = 1;
for (k = 2; ; k++)
if ((fib[k] = fib[k-1] + fib[k-2]) > n)
return k-1;
return 0;
}
unsigned fibSearch(int key)
{ int p,q,r,k;
k = findFib(n);
p = fib[k-1];
q = fib[k-2];
r = fib[k-3];
if (key > m[p].key)
p += n - fib[k] + 1;
while (p > 0)
if (key == m[p].key)
return p;
else
if (key < m[p].key)
if (0 == r)
p = 0;
else {
int t;
p -= r;
t = q;
q = r;
r = t-r;
}
else
if (1 == q)
p = 0;
else {
p += r;
q -= r;
r -= q;
}
return NOT_FOUND;
}

fibsear.c
? ,
. ,
n.
. , -

4 -

258

1, . . .
2.4., , -
, -
45%. , - , 45% -
( 4.3.), - .
:
.

4.5.
"" , ,
"" .
( 4.3.)?
-.
mid mid = (l+r)/2. :
mid = l + (r-l)/2

(*)

, , . ,
.
. (*), 1/2
. ? .
,
, .
X, X, . , :
mid = l + k*(r-l),

k = (x - m[l].key) / (m[r].key - m[l].key)

k, 1/2 . ,
k. , 0, ,
[l,r] . , , k
[0,1]. , mid
[l,r]. k [0,1] ,
.
? ! , k,
- . , - log2 (log2 n) + 1 ,
. ,
, log2 (log2 n) . log2 (log2 1000000000) < 5.
unsigned interpolSearch(int key)
{ unsigned l, r, mid;
float k;

4 -

259

l = 0; r = n - 1;
while (l <= r) {
if (m[r].key == m[l].key)
if (m[l].key == key)
return l;
else
return NOT_FOUND;
k = (float) (key - m[l].key) / (m[r].key - m[l].key);
if (k < 0 || k > 1)
return NOT_FOUND;
mid = (unsigned)(l + k*(r-l) + 0.5);
if (key < m[mid].key)
r = mid - 1;
else if (key > m[mid].key)
l = mid + 1;
else
return mid;
}
return NOT_FOUND;
}

interpol.c
, . , (
) , - , .
, , (
!).
, k [0,1]. . ,
,
. , ,
: 2, .
. , ,
, . . 2 :
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10000

n log2 n log2 (log2 n) , ,


. , ,
, ,
.
:
.

4 -

260

4.6.
4.6.1.
4.1.
, (n+1)/2 (
4.1.).
4.2.

( 4.1.1.). ( 4.1.).
4.3.+
, .
4.1.2. .
4.4.

( 4.1.2.) ( 10.5.).
4.5.

( 4.1.2.). ( 4.1.).
4.6.
-, - :
) ( 4.1.)
) ( 4.1.1.)
) ( 4.1.2.)
4.7.
k l.
k l n ( 4.2.).
4.8.
, - n
n ( 4.2.).
4.9.
n ( 4.3.) 10, 100, 1000
- ( 4.1.)?
4.10.
,
4.3.
4.11.
( 4.3.)
( 4.4.).
4.12.
( 4.3.)
( 4.5.).

4 -

261

4.6.2.
4.13. .
, ,
, .
4.14. .
nm.
4.15. .
.
4.16. .
, k (k )
d. x
, |k x.key| d.

5

"There are two possible outcomes:
If the result confirms the hypothesis,
then you've made a measurement.
If the result is contrary to the hypothesis,
then you've made a discovery."
~ E. Fermi

5.1.
, . - .
.
,
. , .
5.1. (V, E), :

V = {v1, v2, ..., vn}

E = {e1, e2, ..., em} . ek


(k=1,2, ..., m) (vi, vj), vi,vjV, 1 i, j n.
f:ER, ek
f(ek ), . , ,
. ,
, a .
-,
(), , .
1

4
2

12
5

3
8
7

12

11

10
8

13

5.1. .

14

5.1. .

5.1. 14 13 . viV
. , ,

5 -

264

, V,
, V n .

, .
(i,j)E , i j. , : 13. . ,
, 5.1.
, , ( ).
5.2. (V, E), :

V = {v1, v2, ..., vn}

E = {e1, e2, ..., em} .


ek (k = 1,2, ..., m) (vi, vj), vi,vjV, 1 i, j n.
f(i,j),
(i,j)E, f(i,j) = f(j,i), .
1
2
\
2

5.1. .
5.1. ,
(i,j) .
G(V,E)
G(V,E). :
(i,j)E (i,j)E' (j,i)E' G'. ,
, ,
.
. :
1) - .
, . . 5.1.,
, .
2) ,
, , .
3)
.
4)
: . ,
, .

5 -
5)

265


. .

5.1. .
,
. , - -
1), 5).
-
. . -
, .
5.3. () G(V,E).
(.. E ), G .
, , (i,j) ( ) f(1)(i,j), f(2)(i,j), ... .
5.4. G(V,E). i j (i,jV) , (i,j) (j,i) E. , i j
(i,j) (j,i). (i,j) i j, j i. i j (i,j). ,
, . ,
, ,
.
5.5. G(V,E). i, iV
(i,j), jV. , (j,i), jV
i.
i. , 0. i
(i,j), .
5.1a. 2 4, 14 .

5 -

266

5.6. () G(V, E) V'V. E


(i, j), iV' jV', , ,
G'(V',E') V' ( ) G ( 5.1.).

1
2
\
2

2
\
2

1
3

2
\
2

G'(V',E')

G'(V',E)

G(V,E)

5.1. V' = {1, 2, 3} G' G.


5.7. () G(V,E) v1, v2,..., vk , i = 1, 2, , k1 (vi, vi+1)E.
v1 vk . v1 = vk , . i j (1 i, j
k) vi vj, . , v1 = vk ,
, . ,
, .
5.8. G(V, E) G'(V, E'), i, jV, i j,
(i, j) ' E. G'
G. , , ( 5.1.).
(i, j)E i, jV, i j, .
, , .. G' G, G
G'.
1

2
\
2

2
\
2

5.1. .
5.9 G'(V', E') t G, G' , G'
t- G. t, G t- G.
5.10. , i j
(.. i j j i). i, j i j, j i,
. , i, j.

5 -

267

5.11. k, - (, )
i,jV k .
, , k ,
, ,
. , " "
19 [Web-d].
5.12. () G(V, E)
G'(V', E'), :
1) G' () .
2) () G''(V'',E'') G, ,
G' G''.
.
5.13. . ,
.
2.3. ).
5.14. (o) G(V,E)
G'(V, E') G.
:
5.13. 2.2.

5.2.
:

V E.
: () () .

( ) , ,
.
. -
, ,
-, - ( -
).

5.2.1.
- .
(i,j). ,
. () () (i,j,k),
k f(i,j) .
, float A[3][m], m .
, (m),
, -
. , ,

5 -

268

( 4.3.) (log2m). -,
, -: n,
. , , .. ,
: m(n).

5.2.2. ,
-
. n [n][n].
[i][j] 1, (i,j), [i][j] = 0
. ,
(i, j), (j, i), A[i][j] 1 (
1 A[j][i]).
, A[i][j] = 1, (i, j) (j, i),
A[i][j] = 0 . , A[i][j] 1,
i j. , [i][j]
f(i, j), [][] .
.
[i][i] i . ,
, ( (i,i)).

. - (
, , n(n 1)

2
[, , -1995].
, .
(n),
(.. ,
n ).
5.2.2. , 1,
0.
.
0
0
0
1 -1
2
0
3
0
0
4
0
5
6
0
7
0
8
0
0
9
10 0
11 0
12 0

10

11

12

1
0
1
-1
-1
0
0
0
0
0
0
0
0

0
-1
0
0
0
1
0
0
0
0
0
0
0

0
1
0
0
0
0
0
0
0
0
0
-1
0

0
1
0
0
0
0
-1
0
0
0
0
0
0

0
0
-1
0
0
0
1
0
0
0
1
-1
0

0
0
0
0
1
-1
0
0
0
-1
0
0
0

0
0
0
0
0
0
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0
0
0
0
0
0

0
0
0
0
0
0
1
0
0
0
-1
0
0

0
0
0
0
0
-1
0
0
0
1
0
0
0

0
0
0
1
0
1
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0
0
0
0
0
1

4
2
3

13

12

10

11

5.2.2. .

5.2.3. ( )
i .
5.2.2. :

5 -

269

1 {2}; 2 {4,5}; 3 {2}; 4 {12}; 5 {7}; 6 {3,12}; 7 {6,10}; 8 {};


9 {}; 10 {11}; 11{6}; 12 {}; 13 {13}.
- (
2.1.2.).
: ,
(n). ,
, .
:
.
- .
, .
, ,
,
.
.

5.2.4.
nm.
G(V, E), ek = (i, j) k i j,
0. i-
1, j- 1, .
(i,i), i- ek 2.
(
, .),
. , (m.n),
. , ,
(m).

5.2.5.
, , .
, , , ,
-
, .. .
.
,
. ,
,
.
A[n],
1 n. [i] k ... i- k-
. (
(n)), : A[i] A[j], .
( 5.4.2.),
. .
[n][n], A[i][j] 1,
i j, 0 .

5 -

270

5.2.6.
, , :

/ .

/ .
- , :



. , ( ).
/* */
#define MAXN 200
/* */
unsigned n;
/* */
int A[MAXN][MAXN];
/* i */
A[i][i] = k;
/* k, i j */
A[i][j] = k;
A[j][i] = k;
/* */
/* , i j */
A[i][j] = 0;
/* i j */
if (A[i][j] != 0) { /* */; } else { /* */; }
/* i */
for (k = 0; k < n; k++) if (k != i) {
if (A[i][k] != 0) { /* k i */ ; }
}

,
. , ,
-, - .
, , .

(1)

(log2n)

(log2m)

(1)

(n.log2n)

(1)

(log2n)

(log2m)

(m)

5 -

271

(1)

(log2n)

(log2m)

(m)

(n)

(di)

(n+log2m

(m)

(n2)

(n+m)

(n.log2m)

(m )

(1)

(n2)

(m)

(m)

(n.m)

(n)

5.2.6. .
5.2.6. , .
:
5.2.6.,
, : , (log2m) , ,

, .

5.3.
() () .
, .
(
), . :

, .

,
.

, .

5.3.1.
i
: i, ,
- ( ).
, ,
, i.
..
() , .
, BFS(i) ( . Breadth-First-Search),
i.
5.3.1.
1, :
BFS(1):
1: 1
2: 2

5 -

272

3: 3, 4, 5
4: 7, 6, 12
5: 10
6: 11
1 3 , BFS(3) :
BFS(3):
1: 3
2: 2, 6
3: 1, 4, 5, 7, 12
4: 10
5: 11
. ,

. -.
1

3
9

12
7

6
14

10

13

11

5.3.1. .
,
. , ( 5.110.),
.,
.

,
.
,
.
, , , , - (
) .
i.
5.2.6., , , (n).
, n- i
( ,
i ).
(m+n) , (n2)
.
, .
, , : ,
,

5 -

273

. ,
:
BFS(i)
{ ___Queue;
____i;
for (k = 1,2,,n) used[k] = 0;
used[i] = 1;
while (___) {
p = _____;
__p;
for ( j p)
if (0 == used[j]) { /* j */
____j;
used[j] = 1; /* j */
}
}
}

. , -, , 5.3.1.
n, a A[MAXN][MAXN] e .
v.
, -
.
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 14;
/* v */
const unsigned v = 5;
/* */
const char A[MAXN][MAXN] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0}
};
char used[MAXN];
/* */
void BFS(unsigned i)
{ unsigned k, j, p, queue[MAXN], currentVert, levelVertex, queueEnd;
for (k = 0; k < n; k++) queue[k] = 0;
for (k = 0; k < n; k++) used[k] = 0;
queue[0] = i; used[i] = 1;

5 -

274

currentVert = 0; levelVertex = 1; queueEnd = 1;


while (currentVert < queueEnd) { /* */
for (p = currentVert; p < levelVertex; p++) {
/* p */
printf("%u ", queue[p]+1);
currentVert++;
/* j queue[p] */
for (j = 0; j < n; j++)
if (A[queue[p]][j] && !used[j]) {
queue[queueEnd++] = j;
used[j] = 1;
}
}
printf("\n");
levelVertex = queueEnd;
}
}
int main(void) {
printf(" %u: \n", v);
BFS(v-1);
return 0;
}

bfs.c
:
5:
5
2 7
1 3 4 6 10
12 11

:
1. .
, , ?
2. , ,
, ?

5.3.2.
( DFS . Depth-First-Search)
, - ,
( .
backtracking).
, -
. - : iV, , ..
i (DFS(i)) :
1)
2)
3)

i.
i .
i (i,j) , j ,
DFS(j).

5 -

275

DFS 5.3.1. ,
( 2),
- - . DFS(1) : 1, 2, 3, 6, 7, 5,
10, 11, 12, 4, DFS(3): 3, 2, 1, 4, 12, 6, 7, 5, 10, 11.
, , -
( DFS(i)). used[]
: , i used[i] = 1.
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 14;
/* v */
const unsigned v = 5;
/* */
const char A[MAXN][MAXN] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,
{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
};
char used[MAXN];

0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,

0},
0},
0},
0},
0},
0},
0},
0},
1},
0},
0},
0},
1},
0}

/* */
void DFS(unsigned i)
{ unsigned k;
used[i] = 1;
printf("%u ", i+1);
for (k = 0; k < n; k++)
if (A[i][k] && !used[k]) DFS(k);
}
int main(void) {
unsigned k;
for (k = 1; k < n; k++) used[k] = 0;
printf(" %u: \n", v);
DFS(v-1);
printf("\n");
return 0;
}

dfs.c

5 -

276

:
5:
5 2 1 3 6 7 10 11 12 4

5.3.2.
( ).
.


DFS BFS

(n2)

(n + m)

(n.m)

5.3.2. .
, ( )
( 5.14.).
G(V, E) . T(V, D)
:
1) T , , .. D = .
2) G.
i j (i,j) D.
, :
( G , / "" ), ( ).
:
5.3.2.

5.4. ,

- , ,
. 1)
, , ( ),
. ,
( ) ,
(.. , -) .
, , ,
. , ,
( );
,
.. :

(
)
(
)

5 -

277


() ( , ,
). ,
.

, .

5.4.1.
- -
G(V, E) i j. G i
j, .
: BFS(i) , j, ,
, .
5.3.1. 1 10.
BFS(1) :
1: 1
2: 2
3: 3, 4, 5
4: 7, 6, 12
5: 10
j ( j = 10), , j, .
, ? ,
, ..
, .
pred[]:
. i, pred[i] 1. pred[k]
, k:
i

k
pred[k] = k

5.4.1. .
, i j, :
while (j != i) {
(j);
j = pred[j];
}
(j);

(.. j i). , ,
. ,
, .

5 -

278

- ( -
printPath). (n+m). :
#include <stdio.h>
#define MAXN 200 /* */
/* */
const unsigned n = 14;
const unsigned sv = 1; /* */
const unsigned ev = 10; /* */
/* */
const char A[MAXN][MAXN] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,
{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
};

0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,

0},
0},
0},
0},
0},
0},
0},
0},
1},
0},
0},
0},
1},
0}

int pred[MAXN];
char used[MAXN];
/* O */
void BFS(unsigned i)
{ unsigned queue[MAXN];
unsigned currentVert, levelVertex, queueEnd, k, p, j;
for (k = 0; k < n; k++) queue[k] = 0;
queue[0] = i; used[i] = 1;
currentVert = 0; levelVertex = 1; queueEnd = 1;
while (currentVert < queueEnd) { /* */
for (p = currentVert; p < levelVertex; p++) {
/* p - */
currentVert++;
/* j queue[p] */
for (j = 0; j < n; j++)
if (A[queue[p]][j] && !used[j]) {
queue[queueEnd++] = j;
used[j] = 1;
pred[j] = queue[p];
}
}
levelVertex = queueEnd;
}
}
/* */
unsigned printPath(unsigned j)

5 -

279

{ unsigned count = 1;
if (pred[j] > -1) count += printPath(pred[j]);
printf("%u ", j + 1); /* O */
return count;
}
void solve(unsigned start, unsigned end)
{ unsigned k;
for (k = 0; k < n; k++) { used[k] = 0; pred[k] = -1; }
BFS(start);
if (pred[end] > -1) {
printf(" : \n");
printf("\n %u.\n", printPath(end));
}
else
printf(" ! \n");
}
int main(void) {
solve(sv-1, ev-1);
return 0;
}

bfsminw.c
:
:
1 2 5 7 10
5.

:
BFS() ,
ev.

-

e . : . , i , i,
, .
DFS() (
int parent , ).
i , , parent,
. used[],
DFS(i,1) i, .
-1 parent ,
.
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 14;
/* */
const char A[MAXN][MAXN] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

5 -
{1,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
{0,
};

0,
1,
1,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,

1,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,

1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,

1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,

0,
1,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,

280
0,
0,
0,
1,
1,
0,
0,
0,
1,
0,
0,
0,
0,

0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,

0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
1,

0,
0,
0,
0,
0,
1,
0,
0,
0,
1,
0,
0,
0,

0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,

0,
0,
1,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,

0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,

0},
0},
0},
0},
0},
0},
0},
1},
0},
0},
0},
1},
0}

char used[MAXN], cycl;


/* Depth-First-Search */
void DFS(unsigned i, int parent)
{ unsigned k;
used[i] = 1;
for (k = 0; k < n; k++) {
if (cycl) return;
if (A[i][k]) {
if (used[k] && k != parent) {
printf(" ! \n");
cycl = 1;
return;
}
else if (k != parent)
DFS(k, i);
}
}
}

int main(void) {
unsigned k, i;
for (k = 0; k < n; k++) used[k] = 0;
cycl = 0;
for (i = 0; i < n; i++) {
if (!used[i]) DFS(i, -1);
if (cycl) break;
}
if (0 == cycl) printf(" ( )!\n");
return 0;
}

formcycl.c
:
!

(n+m), ,
, (n2).
:
1. ?

5 -

281

2. ?
?

-
. DFS
5.3.2., , , ,
, - .
- , .
,
.
i j, (
6). T ,
, a. ,
, .. . ,
, ,
, ( , ""
).

, i, i j,
( j). ,
,
.
DFS(k) k,
i, .
:
for (k = 0; k < n; k++)
if ([i][k] && !used[k]) allDFS(k, j);

, used[i] = 0
, DFS .
5.3.1. : 2
: 1, 4, 3, 5. 1 . for, 3 DFS(3). 3, DFS(3)
used[3] = 0. -, 4
5, 3.
DFS 3 used[3] = 1,
.
path[], .
, - j, .
allDFS(i,j). : , i, , j.
.
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 14;

5 -

282

const unsigned sv = 1; /* */
const unsigned ev = 10; /* */
/* */
const char A[MAXN][MAXN] = {
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,
{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
{0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
};

0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,

0},
0},
0},
0},
0},
0},
0},
0},
1},
0},
0},
0},
1},
0}

char used[MAXN];
unsigned path[MAXN], count;
void printPath(void)
{ unsigned k;
for (k = 0; k <= count; k++)
printf("%u ", path[k] + 1);
printf("\n");
}
/* i j */
void allDFS(unsigned i, unsigned j)
{ unsigned k;
if (i == j) {
path[count] = j;
printPath();
return;
}
/* */
used[i] = 1;
path[count++] = i;
for (k = 0; k < n; k++) /* i */
if (A[i][k] && !used[k]) allDFS(k, j);
/* : */
used[i] = 0; count--;
}
int main(void) {
unsigned k;
for (k = 0; k < n; k++) used[k] = 0;
count = 0;
printf(" %u %u: \n", sv, ev);
allDFS(sv-1, ev-1);
return 0;
}

btdfs.c
:

5 -

283

1 10:
1 2 3 6 7 10
1 2 4 12 6 7 10
1 2 5 7 10

:
(BFS). ? ?

5.4.2.
5.15. G(V, E) . G
.

. 5.4.1.
.
, ,
/
, - .
,
( ).
,
( ).
, . ,
, . , ,
( ),
, (
) . ,
, , ,
, .
, , .
, .
"" : f(i,j) (i,j) f(i,j).
,
. , ,
.

:
. ( ) , (v1,vk )
p = (v1, v2, ..., vk ) v1 vk . , 1 i < j k p' = (vi, vi+1, ..., vj) vi vj.
v1

vi

vj

vk

5.4.2. .

( ).

5 -

284

- , . , ( , ),
.
- .
:
.

-
-, : -
. d(i,j) i j. ,
i, j, k :
d(i,k) + d(k,j) d(i,j)
d(i,j) + d(j,k) d(i,k)
d(k,i) + d(i,j) d(k,j)
d(j,k) + d(k,i) d(j,i)
d(k,j) + d(j,i) d(k,i)
d(j,i) + d(i,k) d(j,k)
d(x,y) = d(y,x) x,y . ( ) , , .
:

.

- -
G(V, E) - s
. , A[i][j]
G. , (i, j), A[i][j]
+ ( ,
, A).
-:
1)

D[], , D[i]
s i . D[i] = A[s][i],
iV.

2)

D[i], iV - :
jV, D[i] > D[j] + A[j][i], D[i] = D[j] + A[j][i].

5 -
3)

285

2) n2 , D[]
.
for (k = 1; k <= n - 2; k++) /* (n-2) */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (D[i] > D[j] + A[j][i])
D[i] = D[j] + A[j][i];

belman.c
(n3), 2) (n2)
n2 . ,
, D[j] + A[j][i] ( D[j]
A[j][i] ).
- :
, . , ,
( -). - ,
: ,
(i, j) D[i] > D[j] + A[j][i],
(?).
:
1. -.
2. - n-2 , n
n1?
3. , -
(i, j) D[i] > D[j] + A[j][i],
.
4. , : ,
- (i, j),
D[i] > D[j] + A[j][i]?

-
-. ,
,
(
). , A[i][j] (i, j),
[][], A[i][j]
i j.
: i, jV, A[i][j] A[i][j] [i][k]+A[k][j], kV. k,
, -
( ).
(n3). -, , .
k, i j.
, , 0 MAX_VALUE,
(
). , MAX_VALUE
, - n.dmax, dmax (
: ).
: , MAX_VALUE

5 -

286

MAXINT/2, MAXINT int


( MAXINT
<values.h>).
23

34

25

10

30
9

5.4.2. .
.
, 5.4.2. ( , , -,
).
0 (
- ). - ( floyd())
MAX_VALUE.
#include <stdio.h>
/* */
#define MAXN 150
#define MAX_VALUE 10000
/* */
const unsigned n = 10;
/*
const unsigned A[MAXN][MAXN] =
{ 0, 23, 0, 0, 0, 0, 0,
{23, 0, 0, 3, 0, 0, 34,
{ 0, 0, 0, 6, 0, 0, 0,
{ 0, 3, 6, 0, 0, 0, 0,
{ 0, 0, 0, 0, 0, 10, 0,
{ 0, 0, 0, 0, 10, 0, 0,
{ 0, 34, 0, 0, 0, 0, 0,
{ 8, 0, 25, 0, 0, 0, 0,
{ 0, 0, 0, 0, 0, 0, 0,
{ 0, 0, 7, 0, 0, 0, 0,
};

*/
{
8,
0,
25,
0,
0,
0,
0,
0,
0,
30,

0, 0 },
0, 0 },
0, 7 },
0, 0 },
0, 0 },
0, 0 },
0, 0 },
0, 30 },
0, 0 },
0, 0 }

/* */
void floyd(void)
{ unsigned i, j, k;
/* 0 MAX_VALUE */
for (i = 0; i < n; i++) for (j = 0; j < n; j++)
if (0 == A[i][j]) A[i][j] = MAX_VALUE;
/* */
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (A[i][j] > (A[i][k] + A[k][j]))
A[i][j] = A[i][k] + A[k][j];
for (i = 0; i < n; i++) A[i][i] = 0;

5 -

287

}
void printMinPaths(void)
{ unsigned i, j;
printf(" :\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%3d ", (MAX_VALUE == A[i][j]) ? 0 : A[i][j]);
printf("\n");
}
}
int main(void) {
floyd();
printMinPaths();
return 0;
}

floyd.c
:
:
0 23 32 26
0
0 57
8
0 38
23
0
9
3
0
0 34 31
0 16
32
9
0
6
0
0 43 25
0
7
26
3
6
0
0
0 37 31
0 13
0
0
0
0
0 10
0
0
0
0
0
0
0
0 10
0
0
0
0
0
57 34 43 37
0
0
0 65
0 50
8 31 25 31
0
0 65
0
0 30
0
0
0
0
0
0
0
0
0
0
38 16
7 13
0
0 50 30
0
0

, : k -. , -
1, , 1 2, 1, 2 3
.. , i j , .. k, i,
j k, j, i . .
(, , .. ):
const n = 4;
int A[n][n] =
{//
A
B
{ 0, 0,
{ 0, 0,
{ 0, 1,
{ 0, 0,
};

C
6,
0,
0,
2,

D
2},
0},
0},
0}

//
//
//
//

A
B
C
D

, :
0
0
0
0

5
0
1
3

4
0
0
2

2
0
0
0

i, k, j :

5 -

0
0
0
0

7
0
1
3

4
0
0
2

288

2
0
0
0

- A B e (A, D, C, B) 5,
(A, C, B) 7.
.
: ,
-, . .
:
1. (i,j) .
2. (i,j) .

-

:

(k)(i,j) = F { (k1)(i,j), (k1) (i,k) (k1)(k,j) }, (1)(i,j) = f(i,j).


(k) e , , k
, , , , () . , n :
(1)(i,j) , (k)(i,j) . ,
. F
, .
, , F ,
: (n3).
. . , F .
A[][] k-
(k)(i,j). A[][]
(.. A[][] ). F (i,j) ,
[i][j] 0. [i][i] +
(MAX_VALUE). , F (i,j) ,
MAX_VALUE, [i][i] 0.
[i][i] == MAX_VALUE A[i][i] == 0 -
:
if ((i != j)&&(i != k)&&(k != j)) {...}


A[i][i].

5 -

289

1.
, ,
f(i,j) i j ( 0 1). , , . -
. :

(k)(i, j) = max((k1)(i, j), (k1)(i, k). (k1)(k, j) )


A[][], , 0, . () ,
, . - , F
.
2. -
, ,
f(i,j) . s t . ,
. :

(k)(i,j) = max((k1)(i,j), min((k1)(i,k), (k1)(k,j) ),


A[][] 0, . () - , . - , F .
3. t
t
, .
, : (k)(i,j) ,
, . , F
: (x1, x2, ..., xt) (y1, y2, ..., yt) ,
- t , : ,
t x1+ y1, x1+ y2, ..., x1+ yt, x2+y1, x2+y2,..., x2+yt, ..., + xt+y1,
xt+y2,..., xt+yt.
( ), :
, (
) .
, s,
, - .
:
1. ( 1).
2. ( 2).
3. p ( 3).

5 -

290

-
-
.
G(V, E) n . , f(i,j) ( ). sV .
(s,i) s i. -,
: (s,i),
(s,j) + f(j,i), j, j i. , i d[i],
(s, i). , d[i] (s, i):

1) d[] :
d[i] = A[s][i] iV s.
d[i] = MAX_VALUE, i, s.
d[i] == MAX_VALUE .... s i .
2) , , s:
T = V\{s}
3) T i, d[i] < MAX_VALUE:
3.1) j , d[j] .
3.2) j T : T = T \{j}
3.3) iT d[i] = min(d[i], d[j] + A[j][i]);
, ( ),
pred[]. i- pred[]
j, (s, j) + f(j, i) :
if (d[i] > d[j] + A[j][i]) {
d[i] = d[j] + A[j][i];
pred[i] = j;
}

, , -
:
void printPath(unsigned s, unsigned j) {
if (pred[j] != s)
printPath(s, pred[j]);
printf("%d ", j); /* */
}


5.4.1. , ,
.
, -,
5.4.2.
#include <stdio.h>
/* */
#define MAXN 150

5 -

291

#define MAX_VALUE 10000


#define NO_PARENT (unsigned)(-1)
/* */
const unsigned n = 10;
const unsigned s = 1;
/*
const unsigned A[MAXN][MAXN] =
{ 0, 23, 0, 0, 0, 0, 0,
{23, 0, 0, 3, 0, 0, 34,
{ 0, 0, 0, 6, 0, 0, 0,
{ 0, 3, 6, 0, 0, 0, 0,
{ 0, 0, 0, 0, 0, 10, 0,
{ 0, 0, 0, 0, 10, 0, 0,
{ 0, 34, 0, 0, 0, 0, 0,
{ 8, 0, 25, 0, 0, 0, 0,
{ 0, 0, 0, 0, 0, 0, 0,
{ 0, 0, 7, 0, 0, 0, 0,
};

*/
{
8,
0,
25,
0,
0,
0,
0,
0,
0,
30,

0, 0 },
0, 0 },
0, 7 },
0, 0 },
0, 0 },
0, 0 },
0, 0 },
0, 30 },
0, 0 },
0, 0 }

char T[MAXN];
unsigned d[MAXN];
int pred[MAXN];
/* - s */
void dijkstra(unsigned s)
{ unsigned i;
for (i = 0; i < n; i++) /* : d[i]=A[s][i], iV, i != s */
if (0 == A[s][i]) {
d[i] = MAX_VALUE;
pred[i] = NO_PARENT;
}
else {
d[i] = A[s][i];
pred[i] = s;
}
for (i = 0; i < n; i++) T[i] = 1; /* T */
T[s] = 0;
pred[s] = NO_PARENT;
/* , s */
while (1) {
/* T i: d[i] < MAX_VALUE */
/* j T, d[j] */
unsigned j = NO_PARENT;
unsigned di = MAX_VALUE;
for (i = 0; i < n; i++)
if (T[i] && d[i] < di) {
di = d[i];
j = i;
}
if (NO_PARENT == j) break; /* d[i] = MAX_VALUE, i: */
T[j] = 0;
/* j T */
/* i T D[i] = min (d[i], d[j]+A[j][i]) */
for (i = 0; i < n; i++)
if (T[i] && A[j][i] != 0)
if (d[i] > d[j] + A[j][i]) {
d[i] = d[j] + A[j][i];
pred[i] = j;

5 -

292

}
}
}
void printPath(unsigned s, unsigned j)
{ if (pred[j] != s) printPath(s, pred[j]);
printf("%u ", j+1);
}
/* */
void printResult(unsigned s)
{ unsigned i;
for (i = 0; i < n; i++) {
if (i != s) {
if (d[i] == MAX_VALUE)
printf(" %u %u\n", s+1, i+1);
else {
printf(" %u %u: %u ", s+1, i+1, s+1);
printPath(s, i);
printf(", : %u\n", d[i]);
}
}
}
}
int main(void) {
dijkstra(s-1);
printResult(s-1);
}

dijkstra.c
:
1
1
1
1
1
1
1
1
1

2:
3:
4:
5
6
7:
8:
9
10:

1 2 , : 23
1 2 4 3 , : 32
1 2 4 , : 26

1 2 7 , : 57
1 8 , : 8
1 8 10 , : 38

(n2). -
(, 3.1.9., [Cormen, Leiserson,
Rivest-1997]) (n.log2n).
: ,
. , (
5.4.2.).
2
B

A
3
3

2
C

5.4.2. .

5 -

293

B C, :
1) d[A] = 0, d[B] = f(A,B) = 2, d[C] = f(A,C)=3.
2) T = {A,B,C}\{A} = {B,C}.
3) iT, d[i] , B:
B T. T ( T C)
: d[C] = min(d[C], d[B] + f(B,C)) = min(3, 2+3) = 3.
T C, C T
.
d[A] = 0, d[B] = 2, d[C] = 3. , - B
2, 1 ( A-C-B, 3+(2) = 1).
:
1. - .
2.
d[], pred[]?

-
k
k .
G(V, E) A[][]. A' e , A'[i][j]
k i j. A" = A'.A
A"[i][j] k+1 .
:
A"[i][j] =

A'[i][t].A[t][j]

t 1

A'[i][t] k i t,
k+1 i j A'[i][t] , (t, j) (
A[t][j] == 1).
. G(V, E) . A k, C[i][j] = Ak[i][j] k, i j. C[i][j] = 0, , i j k.
( ),
1, "" .
, "": , . (,
,
). ,
, , ,
.
a :
.

-
G(V, E) A[][].
[][], :

[i][j] == 1, , (

) i j.
[i][j] == 0, .

5 -

294

[][], . G(V, E),


[][] ( [][] )
G ( 5.5.1.).
(n3) :
k, i, jV, (i, k) (k, j),
(i, j) ( 5.4.2.).
i


j
k

5.4.2. .

:
for (k = 0; k < n; k++)
for (i = 0; i < n; i++) {
if (A[i][k])
for (j = 0; j < n; j++)
if (A[k][j]) A[i][j] = 1;
}

, A[][]
[][]. (?)
. :
.
:
1. .
2. , .

- -
, -
. ,
. ,
, (
, 8)
-.
.
: ,
.
: . ,
. , ,
. ( , ), . , .
,
, ,

5 -

295

. .
- ( 8).
:
G(V, E) A[N][N] G.
1) maxDist[],
, .. maxDist[i] i.
maxDist[] .
savePath[] - , 1.
2) iV, .
, ( !).
k :
maxDist[k] = max { maxDist[k], maxDist[i] + A[k][i] }

3)

2), .
maxDist[i], i=1,2,n .

(n+m),
(n2). . 5.4.2.
, maxDist[].
:
- .
. DFS(i),
j i.
maxDist[j]+A[j][i], j i , DFS,
maxDist[i]. DFS(i) , maxDist[i]
, .. maxDist[i] == 0 ( ).
DFS .
, ,
savePath[] i j,
maxDist[i]+A[i][j].
12

40

3
17

20

30
4

20
5

1. maxDist[i]=0, i.
2. 3 =>
maxDist[6] = max{ maxDist[6], maxDist[3]+20} = max{0, 20} =20;
, maxDist[2] = 40
3. 6 => maxDist[5] = 40;
4. 5 =>
maxDist[4] = 70, maxDist[2] = max{ 40, 40+17} = 57
5. 4
6. 2 => maxDist[1] = 69
7. 1

- : 70 (maxDist[4])

5 -

296

5.4.2. .
. A[][]
.
#include <stdio.h>
/* */
#define MAXN 150
/* */
const unsigned n = 6;
/* */
const unsigned A[MAXN][MAXN] = {
{ 0, 12, 0, 0, 0, 0 },
{ 0, 0, 40, 0, 17, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 30, 0 },
{ 0, 0, 0, 0, 0, 20 },
{ 0, 0, 20, 0, 0, 0 }
};
int savePath[MAXN], maxDist[MAXN];
void DFS(unsigned i)
{ int max, d;
unsigned j;
if (maxDist[i] > 0) return;
max = maxDist[i];
for (j = 0; j < n; j++)
if (A[i][j]) {
DFS(j);
d = maxDist[j] + A[i][j];
if (d > max) {
max = d;
savePath[i] = j;
}
}
maxDist[i] = max;
}
void solve(void)
{ unsigned i, maxi;
/* */
for (i = 0; i < n; i++) {
maxDist[i] = 0;
savePath[i] = -1;
}
for (i = 0; i < n; i++)
if (maxDist[i] == 0) DFS(i);
maxi = 0;
for (i = 0; i < n; i++)
if (maxDist[i] > maxDist[maxi])
maxi = i;

5 -

297

printf(" %d\n : ", maxDist[maxi]);


while (savePath[maxi] >= 0) {
printf("%u ", maxi + 1);
maxi = savePath[maxi];
}
printf("%d\n", maxi + 1);
}
int main(void) {
solve();
return 0;
}

longpath.c
:
70
: 4 5 6 3

:
1. , :


2. ,
, .

- -
, - NP-
, 6.3.3. .
:
1. i j, - i j.
2. , -
? ? ?
.

5.4.3.
5.4.2. .

-
G(V, E) n m . D(V, T) G. D , T,
. , G D.
D q = n1 . G, D,
mn+1. T
, mn+1.

5 -

298

, , G ""
, . , 5.4.3. ( - )
A = (1, 2, 3), B = (4, 5, 6) C = (2, 3, 4, 6).
() A, B C, (
/ !).
( )
. , A C, (1, 2, 4, 6, 3).
1

5.4.3. .
,
DFS.
, - ,
,
, - DFS2().
(m.(m+n)).
, -, [][],
[i][j] i j. , ,
[i][j] == 2, .
#include <stdio.h>
/* */
#define MAXN 150
/* */
const unsigned n = 10;
/* , : 0 - ; 1 ;
* - 2 .
*/
char A[MAXN][MAXN] = {
{ 0, 1, 1, 0, 0, 0 },
{ 1, 0, 1, 1, 0, 0 },
{ 1, 1, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 1, 1 },
{ 0, 0, 0, 1, 0, 1 },
{ 0, 0, 1, 1, 1, 0 }
};
char used[MAXN];
unsigned cycle[MAXN], d;
/* */
void DFS(unsigned v)
{ unsigned i;
used[v] = 1;
for (i = 0; i < n; i++)
if (!used[i] && A[v][i]) {

5 -

299

A[v][i] = 2;
A[i][v] = 2;
DFS(i);
}
}
/* */
void printCycle(void)
{ unsigned k;
for (k = 0; k < d; k++)
printf("%u ", cycle[k] + 1);
printf("\n");
}
/* */
void DFS2(unsigned v, unsigned u)
{ unsigned i;
if (v == u) { printCycle(); return; }
used[v] = 1;
for (i = 0; i < n; i++)
if (!used[i] && 2==A[v][i]) {
cycle[d++] = i;
DFS2(i, u);
d--;
}
}
int main(void) {
unsigned i, j, k;
DFS(0);
printf(" : \n");
for (i = 0; i < n - 1; i++)
for (j = i + 1; j < n; j++)
if (1 == A[i][j]) {
for (k = 0; k < n; k++) used[k] = 0;
d = 1;
cycle[0] = i;
DFS2(i, j);
}
return 0;
}

allcyc.c
:
:
1 2 3
2 3 6 4
5 4 6

:
1. (/ ) ?
2. (/ ) ? ?
3. - (m.(m+n)), , (n4).
? ,

5 -

300

(m+n), h ,
.. ((m+n).h). ,
- , ..
((m+n).n).
,
((m+n).h)?
, ? , h O(log2n)?

-
: G(V, E) iV. (
), i,
.
: jV (i,j) i j (j, i)
j i. Sk = (i, k) + (k, i), kV. Sk
, .
, . ,
,
. , :

. ( ) 5.5.

, k ( 5.93.).
"" , k = n, .
:
1. .
2. . , , .

5.4.4. .
5.16. () ,
. , , .
1. ,
.

,
. NP- ( 6.2.), ,
- .
.

. 5.4.1.
. ,
. i , , . curSum , ,
. ,

5 -

301

- -, (
minSum), - . , -,
( 6.4.). : curSum ,
, - minSum,
. , - ,
- -.
, , , curSum
! , :
int A[n][n] =
{
// A B C
{ 0, 1, 2,
{ -2, 0, 1,
{ 0, 0, 0,
{ 1, 2, 0,
};

D
0},
0},
1},
0}

//
//
//
//

A
B
C
D


(A,B,C,D,A) 1+1+1+1 = 4,
(A,C,D,B,A) 2+1+2 = 5. 5 > 4, 4
, , ,
(,) 2, 3, 3 < 4.
A[][],
. ,
, 5.4.4.
5

6
7

3
7

4
3

5.4.4. .
#include <stdio.h>
/* */
#define MAXN 150
#define MAX_VALUE 10000
/* */
const unsigned n = 6;
/* */
const int A[MAXN][MAXN] = {
{ 0, 5, 0, 0, 7, 7 },
{ 5, 0, 5, 0, 0, 0 },
{ 0, 5, 0, 6, 5, 0 },
{ 0, 0, 6, 0, 3, 3 },
{ 7, 0, 5, 3, 0, 5 },
{ 7, 0, 0, 3, 5, 0 }
};

5 -

302

char used[MAXN];
unsigned minCycle[MAXN], cycle[MAXN];
int curSum, minSum;
void printCycle(void)
{ unsigned i;
printf(" : 1");
for (i = 0; i < n - 1; i++) printf(" %u", minCycle[i] + 1);
printf(" 1, %d\n", minSum);
}
/* */
void hamilton(unsigned i, unsigned level)
{ unsigned k;
if ((0 == i) && (level > 0)) {
if (level == n) {
minSum = curSum;
for (k = 0; k < n; k++) minCycle[k] = cycle[k];
}
return;
}
if (used[i]) return;
used[i] = 1;
for (k = 0; k < n; k++)
if (A[i][k] && k != i) {
cycle[level] = k;
curSum += A[i][k];
if (curSum < minSum) /* */
hamilton(k, level + 1);
curSum -= A[i][k];
}
used[i] = 0;
}
int main(void) {
unsigned k;
for (k = 0; k < n; k++) used[k] = 0;
minSum = MAX_VALUE;
curSum = 0;
cycle[0] = 1;
hamilton(0, 0);
printCycle();
return 0;
}

tsp.c
:
: 1 2 3 5 4 6 1, 28.

:
50 , . , [Reinelt-1994].
(!) , (,
n ) .
,
, . ,
,

5 -

303

. , ( 5.8.)
( , ).
(- ), ,
.
. , 2,
.
0 1.
, ,
ln n + ln ln n [Christofides-1975].
:
,
( ). 9.1.8.

5.4.5.
,
.. ( )
, , 5.4.5.
B

5.4.5,.
.

:
http://guide.kaliningrad.net/map.php3?language=eng.

,

. ( 5.4.5.) ,
.
5.17. . , , .
, .
.

5 -

304

. () ( ,
). ,
, .
1. , .
2. ,
, d+(i) i d(i),
..: d+(i) = d(i), iV.
2.
, i j, d+(i) = d (i)+1, d+(j) = d (j)1 d+(k) = d (k),
kV, k i, k j.
1. ,
.
3. , , - .
5.4.5.
(1,2), (2,3), (3,4), (4,2), (2,5), (5,3), (3,5), (5,6), (6,3), (3,7), (7,8), (8,1).

i.
(i,j) . j:
(j,k), k. , i, .. (?).
, . ,
x, - , e .
, , , x
(.. ) . x ,
. , (
x). , ,
.
, ,
: ( 1 ,
) - .
.
1

3
4
8

6
7

5.4.5. .
A[][].
: stack[], , cStack[]

5 -

305

. .
- :
___i__stack;
while (stack___) {
__i____stack____;
if (i__) {
___j__i;
_j__stack;
A[j][i] = 0; A[i][j] = 0; /* */
} else {
_i__stack;
_i__cStack;
}
}

. 5.4.5.
#include <stdio.h>
/*
#define MAXN 100
/* */
const unsigned n = 8;
/*
char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0, 0, 0, 0
{ 0, 0, 1, 0, 1, 0, 0, 0
{ 0, 0, 0, 1, 1, 0, 1, 0
{ 0, 1, 0, 0, 0, 0, 0, 0
{ 0, 0, 1, 0, 0, 1, 0, 0
{ 0, 0, 1, 0, 0, 0, 0, 0
{ 0, 0, 0, 0, 0, 0, 0, 1
{ 1, 0, 0, 0, 0, 0, 0, 0
};

*/

*/
},
},
},
},
},
},
},
}

/* ( ) */
char isEulerGraph(void)
{ unsigned i, j;
for (i = 0; i < n; i++) {
int din = 0, dout = 0;
for (j = 0; j < n; j++) {
if (A[i][j]) din++;
if (A[j][i]) dout++;
}
if (din != dout) return 0;
}
return 1;
}
/* */
void findEuler(int i)
{ unsigned cStack[MAXN * MAXN], stack[MAXN * MAXN];
unsigned k, j, cTop = 0, sTop = 1;
stack[sTop] = i;
while (sTop > 0) {
i = stack[sTop];
for (j = 0; j < n; j++)

5 -

306

if (A[i][j]) {
A[i][j] = 0; i = j;
break;
}
if (j < n)
stack[++sTop] = i;
else
cStack[++cTop] = stack[sTop--];
}
printf(" : ");
for (k = cTop; k > 0; k--) {
printf("%u ", cStack[k] + 1);
}
printf("\n");
}
int main(void) {
if (isEulerGraph()) findEuler(0);
else
printf(" !");
return 0;
}

euler.c
:
: 1 2 3 4 2 5 3 5 6 3 7 8 1

:
1. .
2. .
- ?

5.4.6.
G(V, E), :

,
.

5 -

307
5.4.6. .

,
, ,
. (i,j) "",
i j, :
1)
2)

c: c(i,j) ,
(i,j), c(i,j) 0, (i, j) E.
t: t(i,j) ()
(i,j).

( . minimum cost network flow


problem) , . 1960 . ( out of kilter) . , :

n , n nn: aij i j. ( p 1 n) , (..
).
a

iV

i , p (i )

, .

, .

, , .

().
: ( , )
.
, . .
[-1995].

-
.
,
(, , ) . , , 1950 .
.
G(V, E), (i,j) c(i, j), ( ). : s t.
5.18. f:Z, (i,
j) f(i, j) :
1)
2)

, .. (i, j)E f(i, j) c(i, j).


, , " ". ,
i j f(i, j), , j i
f(i,j), (i, j)E.

5 -
3)

308

, .. iV\{s, t}

f (i, j ) 0 .

j:( i , j )E

s t, .. f ( ),
f (i, t ) .

i:( i ,t )E

-
, :
1) : f(i, j) = 0, (i, j)E.
2) . (s = v0, v1, ...,vk = t)
s t, vi, vi+1 (i = 0,1,..., k1) c(vi, vi+1) > 0.
3) , , .
4) p, , ..:

p min c(vi , vi 1 )
i 0,...,k 1

f(vi,vi+1) = f(vi,vi+1) + p, i = 0,1,...,k1


f(vi+1,vi) = f(vi+1,vi) p, i = 0,1,...,k1
( )
- :
c(vi,vi+1) = c(vi,vi+1) p, i = 0,1,...,k1
c(vi+1,vi) = c(vi+1,vi) + p, i = 0,1,...,k1
2, ..
5.4.6., s = 1 t = 6.
5 :
1. (1, 2, 3, 5, 6): (2,3)
: 4. , 2
3 4, ( 3)
.
2. (1, 2, 6): (1,2) 1 (
4 1).
3. (1, 3, 2, 6): (3,2) 4.
4. (1, 3, 5, 6): (1,3) 1.
5. (1, 4, 6): (4,6) 7.
17.
10
1

5
3

8
5

7
5.4.6. .

, , [Christofides-1975]. , ( 2 ), -

5 -

309

, .. . ( 5.4.6.) .
-
: s-1-2-t .
(2), s-2-1-t (3),
, .. 1000000
[Cormen, Leiserson, Rivest-1997].
, [Cormen,
Leiserson, Rivest-1997]:
. ( ) , 2), , -
(n5), .. - n3 ,
(n2).
1000000

(1)

999999

1000000

999999

s
999999

1000000

s
1000000

(3)

999999

(2)

1
1

s
1000000

1000000
t
999999

t
999999

5.4.6. .
- , A[][], F[][].
#include <stdio.h>
/* */
#define MAXN 100
#define MAX_VALUE 10000
const unsigned n = 10; /* */
const unsigned s = 1; /* - */
const unsigned t = 6; /* - */
/* */
int A[MAXN][MAXN] = {
{ 0, 5, 5, 10, 0, 0 },
{ 0, 0, 4, 0, 0, 5 },
{ 0, 0, 0, 0, 7, 0 },
{ 0, 0, 0, 0, 0, 7 },
{ 0, 0, 0, 0, 0, 8 },
{ 0, 0, 0, 0, 0, 0 }
};
int F[MAXN][MAXN];

5 -
unsigned path[MAXN];
char used[MAXN], found;
void updateFlow(unsigned pl)
{ int incFlow = MAX_VALUE;
unsigned i;
printf(" : ");
for (i = 0; i < pl; i++) {
unsigned p1 = path[i];
unsigned p2 = path[i + 1];
printf("%u, ", p1+1);
if (incFlow > A[p1][p2]) incFlow = A[p1][p2];
}
printf("%u \n", path[pl]+1);
for (i = 0; i < pl; i++) {
unsigned p1 = path[i];
unsigned p2 = path[i + 1];
F[p1][p2] += incFlow;
F[p2][p1] -= incFlow;
A[p1][p2] -= incFlow;
A[p2][p1] += incFlow;
}
}
void DFS(unsigned i, unsigned level)
{ unsigned k;
if (found) return;
if (i == t-1) {
found = 1;
updateFlow(level - 1);
}
else
for (k = 0; k < n; k++)
if (!used[k] && A[i][k] > 0) {
used[k] = 1;
path[level] = k;
DFS(k, level + 1);
if (found) return;
}
}
int main(void) {
unsigned i, j;
int flow;
/* 1) */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) F[i][j] = 0;
/* 2) , */
do {
for (i = 0; i < n; i++) used[i] = 0;
found = 0;
used[s-1] = 1;
path[0] = s-1;
DFS(s-1, 1);
} while (found);
/* */

310

5 -

311

printf(" : \n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) printf("%4d", F[i][j]);
printf("\n");
}
printf("\n");
flow = 0;
for (i = 0; i < n; i++) flow += F[i][t-1];
printf(" : %d\n", flow);
return 0;
}

fordfulk.c
:
: 1, 2,
: 1, 2,
: 1, 3,
: 1, 3,
: 1, 4,
:
0
5
5
7
0
0
0
-5
0
0
0
0
5
0
-5
0
0
0
5
0
0
-7
0
0
0
0
7
0
0
0 -5
0
0
5
0
0 -5
0 -7 -5
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

3, 5, 6
6
2, 6
5, 6
6
0
0
0
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0
0
0

: 17

, , - ,
.
,
(n4) (n3) [Cormen, Leiserson, Rivest-1997].
:
, , .

-
,
- . s1, s2,, sp, a t1, t2,, tq.
s , t .
, :

(s, si), c(s, si) = +, i = 1, 2, , p.


(tj, t), c(tj, t) = +, j = 1, 2, , q.

5 -

312

- s t, .
(?)
:
, -
, .

-
, . v(i), v(i) 0, iV :

f (i, j ) v(i), iV
jV

s t. , . G'(V',E'), :
1)
2)
3)

iV V': i1 i2,
(i1, i2). c(i1, i2) v(i).
(i, j) G G' (i2, j1).
G' v, .

, - G', a G. (?)
5.6.4. 5.7.6.
:
, -
.

5.5. .

,
.
.
.
, -. , "",
. . A B ( ),
, .. (A, B),
B, A - B.
, .
.
, .
, , ,
.

5 -

313

5.5.1. .
5.4.2. , . A
A. , G A
G.
- , . ( ) G(V,E) : (i,j)E .... i j. G(V,E) G, (i,j)E ... i e ( ) j.
. : ,
. t, S,
, t. , ,
.
. ,
,
- ( 5.5.5 ).
5.4.2:
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
if (A[i][k])
for (j = 0; j < n; j++)
if (A[k][j])
A[i][j] = 1;

. () (i, j, k) for , -,
[Brassard,Bratley1996].
, .
- ( 8)
:
A[i ][ j ], k 0

Ak [i ][ j ]

min
A
[
i
][
j
],
A
[
i
][
k
]

A
[
k
][
j
]
,
k

0
k 1
k 1
k 1

. , , :
for (i = 0; i < n; i++)
for (k = 0; k < n; k++) if (A[i][k])
...

,
. (?)
:
1. .
2. , . ,
.

5 -

314

5.5.2.
5.19. G(V,E). (i,j) E, ..
.
5.20. G(V,E),
i,j,kV : (i,k) (k,j), , (i,j). G
.
5.21. G(V,E) ,
, . .
.
,
, ( , ).
i-j , iV jV , . ij , i j; ij j i, a i j i j.
( i, j, kV):
R1. ij, jk, i k, jk: kj.
R2. ij, ik, j k, ik: ik.

.
, ,
, .
2) R1 R2, , :
ij. kV, j, 2.1), k, i 2.2).
2.1). (j,k)
a.( R1) i k jk, (j,k) jk
.( R1) i k jk,
.
2.2). (i,k)
a.( R2) j k ik, (i,k) ik.
.( R2) e j k ik
.
3) . ,
. ,
,
1).
5.5.2.
1)

5 -

315

5.5.2. .
, -, A[][].
(i,j) , A[i][j] == 1 A[j][i] == 1.
0. ij ij,
A[i][j] = 2 A[j][i] = -2. 3)
, ,

. : A[i][j] == 2 (
A[j][i] == -2) A[i][j] = -3 A[j][i] = -4.
(i, j) if (A[i][j] > 0).
:
#include <stdio.h>
/* */
#define MAXN 150
/* */
const unsigned n = 6;
/* */
int A[MAXN][MAXN] =
{
{ 0, 1, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 0 },
{ 0, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 1, 0 }
};
/* //
const unsigned n = 5;
int A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 1},
{ 1, 0, 1, 0, 0},
{ 0, 1, 0, 1, 0},
{ 0, 0, 1, 0, 1},
{ 1, 0, 0, 1, 0}};
*/
char trOrient(void)
{ /* */
unsigned i, j, k, r, tr = 0;
char flag;

5 -

316

for (i = 0; i < n - 1; i++)


for (j = i + 1; j < n; j++)
if (A[i][j]) tr++;
r = 0;
do {
for (i = 0; i < n; i++) { /* 1 (i,j) */
for (j = 0; j < n; j++)
if (1 == A[i][j]) {
A[i][j] = 2;
A[j][i] = -2;
break;
}
if (j<n) break;
}
/* 1) 2), */
do {
flag = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (2 == A[i][j]) {
for (k = 0; k < n; k++) {
if (i != k && j != k) {
if (0 == A[i][k] || A[i][k] < -2) { /*
/* a) ->
if (2 == A[j][k]) return 1;
/* b) -> (j,k) */
if (1 == A[j][k])
{ A[k][j] = 2; A[j][k] = -2; flag = 1; }
}
if (0 == A[j][k] || A[j][k] < -2) { /*
/* a) ->
if (2 == A[k][i]) return 1;
/* b) -> (i,k) */
if (1 == A[i][k]) {
A[i][k] = 2;
A[k][i] = -2;
flag = 1;
}
}
}
}
}
}
}
} while (flag);

2.1) */
*/

2.2) */
*/

/* 3 */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (2 == A[i][j]) {
A[i][j] = -3; A[j][i] = -4; r++;
}
} while (r < tr);
/* , */
return 0;
}

5 -

317

void printGraph(void)
{ unsigned i, j;
printf(" : \n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
if (-3 == A[i][j]) printf(" 1");
else (-4 == A[i][j]) ? printf(" -1") : printf("
printf("\n");
}
}
int main(void) {
if (trOrient())
printf(" ! \n");
else
printGraph();
return 0;
}

0");

trans-or.c
:
:
0 1 0 0 0 1
-1 0 -1 0 0 0
0 1 0 1 0 0
0 0 -1 0 -1 0
0 0 0 1 0 1
-1 0 0 0 -1 0

:
, , .

5.5.3.
5.22. G(V, E) W.
G'(V,E'), E'E, , W,
G.

1
2
3
4
5
6

1
1
1
1
0
0
0

2
1
1
1
0
0
0

3
1
1
1
0
0
0

4
1
1
1
1
1
1

5
1
1
1
1
1
1

6
1
1
1
1
1
1

5.5.3. .
, 5.5.3. ()
, , .

G(V,E) W.

A[][] , W[][].
A[][], (

5 -

318

A[][]
).
k = 1, 2, ..., n i j, :

(i, k), .. A[i][k] == 1.


k j, .. W[k][j] == 1.
(i, j) (A[i][j] == 1),
, .

, k -:
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
if (A[i][k])
for (j = 0; j < n; j++)
if (A[i][j] && W[k][j]) A[i][j] = 0;

:
, E'E , .. ( )
?
?

5.5.4.
: G(V,E)
0 100. , i j, (i,j), f(i,j) > 50 v1, v2,..., vk , i, (v1,j),
(v2,j),..., (vk ,j) f(v1, j) + f(v2, j) + ... + f(vk , j) > 50. m
m .
, ,
(i, j) , i j.
5.5.4.: 1
2, 4 5.

10
6

10
25

20

55
31

20

6
2

45

5.5.4. .
. control[], i
. i
. , , i, ,
, control[]. , -

5 -

319

i, , control[] 50.
(n3).
#include <stdio.h>
/* ( ) */
#define MAXN 150
/* ( ) */
const unsigned n = 6;
const unsigned m = 1;
/* T 1 */
/* */
const unsigned A[MAXN][MAXN] = {
{ 0, 6, 10, 20, 55, 20 },
{ 0, 0, 0, 0, 0, 25 },
{ 0, 0, 0, 0, 0, 10 },
{ 0, 45, 0, 0, 0, 0 },
{ 0, 0, 0, 31, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
unsigned control[MAXN];
char used[MAXN];
void addControls(void)
{ unsigned i, j;
for (i = 0; i < n; i++)
/* i , m */
if (control[i] > 50 && !used[i]) {
for (j = 0; j < n; j++) control[j] += A[i][j];
used[i] = 1;
}
}
void solve(void)
{ unsigned i;
for (i = 0; i < n; i++) {
control[i] = 0;
used[i] = 0;
}
for (i = 0; i < n; i++) control[i] = A[m-1][i];
for (i = 0; i < n; i++) addControls();
}
void printResult(void) {
unsigned i;
printf(" %u : \n", m);
for (i = 0; i < n; i++)
if (control[i] > 50) printf("%u: %3u% \n", i, control[i]);
printf("\n");
}
int main(void) {
solve();
printResult();
}

company.c

5 -

320

:
1 :
1: 53%
3: 51%
4: 55%

:
, - (n3)?

5.5.5.
5.23. To G(V, E)
Z , : i,
jV, i j, i j Z.
, Z .
5.24. Z, Z .
5.25. G(V,E).
Z, G, .... G .
1: :
( ), , , ,
.
q , .
, -
.
q , .
q
Z.
2: .
, , . ,
" " ,
/ -.
,
, . (?)
(, ) .
- ,
1
1) Z .
2) i Z. i
, , .
3) 2), .
:
1. 2) , .
(?)

5 -

321

2. 2) , ,
, ,
. : ,
. (?)
-,
( ). numi iV. numi (n+m)
. , i1, i2, , ik i,
numi1, numi2,, numik . -, j,
numj = 0. Z, numj
j . n (
). (n2), (m+n)
:
1)

2)

Z , ,
. ,
Z ( Z).
i, . j
numj . numj , j
Z. Z 2).

, - n 2)
Z .
2
, , (m+n), 1. :
.
,
:
void DFS(unsigned i)
{ unsigned k;
used[i] = 1;
for (k = 0; k < n; k++)
if (A[i][k] && !used[k]) DFS(k);
printf("%u ", i + 1);
}

, DFS 5.3.2.
i. ,
, , , .
main DFS(i) i,
. , used[],
. :
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 5;

5 -

322

/* */
const char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 1 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0 }
};
char used[MAXN];
/* DFS */
void DFS(unsigned i)
{ unsigned k;
used[i] = 1;
for (k = 0; k < n; k++)
if (A[i][k] && !used[k]) DFS(k);
printf("%u ", i + 1);
}
int main(void) {
unsigned i;
/* */
for (i = 0; i < n; i++) used[i] = 0;
printf(" ( ): \n");
for (i = 0; i < n; i++)
if (!used[i]) DFS(i);
printf("\n");
return 0;
}

topsort.c
:
( ):
4 3 5 2 1

:
1. 5.25.
2. , 2 1 , .

5.5.6.
1

5.5.6. .
5.5.6. G
Z=(1, 2, 7, 3, 4, 6, 5, 8) Z=(6, 1, 2, 5, 7, 3, 8, 4).
( -) ,
Z 56. (?)

5 -

323

1 5.5.5.
, , . . Z, . ,
,
( , ). -
fullTopSort().
fullTopSort() .
. ,
Z n , .
:
fullTopSort(count) {
if (count == n) {
____=>__;
return;
}
for ( Vi _)
_Vi__;
fullTopSort(count + 1); /* */
_Vi__;
}
}

:
#include <stdio.h>
#define MAXN 200 /* */
/* */
const unsigned n = 8;
/* */
char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
char used[MAXN];
unsigned topsort[MAXN], total = 0;
void printSort(void)
{ unsigned i;
printf(" %u: ", ++total);
for (i = 0; i < n; i++) printf("%u ", topsort[i] + 1);
printf("\n");
}
void fullTopSort(unsigned count)
{ unsigned i, j, k, saved[MAXN];
if (count == n) { printSort(); return; }

5 -

324

/* */
for (i = 0; i < n; i++) {
if (!used[i]) {
for (j = 0; j < n; j++)
if (A[j][i]) break;
if (j == n) {
for (k = 0; k < n; k++) {
saved[k] = A[i][k]; A[i][k] = 0;
}
used[i] = 1;
topsort[count] = i;
fullTopSort(count + 1); /* */
used[i] = 0;
for (k = 0; k < n; k++) A[i][k] = saved[k];
}
}
}
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) used[i] = 0;
fullTopSort(0);
return 0;
}

topsortf.c
:

1:
2:
3:
4:
5:

1
1
1
1
1

49:
50:
51:
52:
53:
54:
55:
56:

2
2
2
2
2

6
6
6
6
6
6
6
6

6
6
6
6
6

1
1
5
5
5
5
5
5

5
5
5
5
7

5
5
1
1
1
1
1
8

7
7
7
8
3

2
8
2
2
2
2
8
1

3
3
8
7
4

8
2
7
7
7
8
2
2

4
8
3
3
5

7
7
3
3
8
7
7
7

8
4
4
4
8

3
3
4
8
3
3
3
3

4
4
8
4
4
4
4
4

:

5.5.6.

5.5.7.
: G(V, E). G(V, E), :

EE

Z, G.
, , G, Z G.

5 -

325

:
, , .
:
A :
( ) i j A[i][j] A[j][i]
, . (?)
1
, , :
1) , i,jV, i j, A[i][j] == 0
A[j][i] == 0, A[i][j] = 1
2) 1), ( ) i, j (.. 2
n n .
2

(n4) . (?)
2
Z = (vi1, vi2,,vin).
G :
for (j = 0; j < n-1; j++)
for (k = j+1; k < n; k++)
if (___(vij,vik)) { (vij,vik); }

- 1 (n2). (?)
:
1. 1.
2. G(V, E). G(V, E), :

EE

Z, G.

E .
- , ?

5.5.8.
: .
(.. ). , ..
, .
: .
: ,
i, d(i). , , d(i) , - , i.
, i 0. , .
( ?). , , -
- .
.
- (n2.log2n): n ,
. , , ,

5 -

326

1, (?),
(n2).
:
1. , ?
2. , ?
3. , , , .
4. .
5. (m+n)? -?

5.6.
, , .
: ,
. ,
:

: , , ..
. ,
.

: -
.

: ,
, .. , , ,
.

.

5.6.1.
: . , ..
. , ,
, .. .

, :
1) , , .
, , .
2) , , . . 2), .
(n+m).
.
.
#include <stdio.h>
/* */

5 -

327

#define MAXN 200


/* */
const unsigned n = 6;
/* */
const char A[MAXN][MAXN] = {
{ 0, 1, 1, 0, 0, 0 },
{ 1, 0, 1, 0, 0, 0 },
{ 1, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 1 },
{ 0, 0, 0, 1, 0, 1 },
{ 0, 0, 0, 1, 1, 0 }
};
char used[MAXN];
/* DFS */
void DFS(unsigned i)
{ unsigned k;
used[i] = 1;
printf("%u ", i + 1);
for (k = 0; k < n; k++)
if (A[i][k] && !used[k]) DFS(k);
}
int main(void) {
unsigned i, comp;
/* */
for (i = 0; i < n; i++) used[i] = 0;
printf("\n : \n");
comp = 0;
for (i = 0; i < n; i++)
if (!used[i]) {
comp++;
printf("{ ");
DFS(i);
printf("}\n");
}
if (1 == comp)
printf(" .\n");
else
printf(" : %d \n", comp);
return 0;
}

strcon1.c
:
{ 1 2 3 }
{ 4 5 6 }
: 2

:

.

5 -

328

5.6.2.
5.10.: G(V,E) ,
i j, j i, o i j, i, jV.
, (
G).
, , ,
, .
1
1) iV.
2) DFS(i) R, i.
3) G'(V,E'): , .. (j,k)E' .... (k,j)E.
4) i G'
Q, i G' ( i G).
5) R Q .
6) , ,
1).
(n . (n + m)). ,
, (m+n).
2
, ,
: , -
. (
postnum) , DFS(i),
:
postnum[i] = count++;,
count ( ).
:
1) G,
postnum, -.
2) G'(V,E'), G: ,
, .. (j,i)E' , (i,j)E.
3) G'.
w, postnum[w] - . ,
, . ,
,
postnum -. , .
. - ,
2) .
G',
(backDFS), G , ,
G'. , : ,
.
#include <stdio.h>
const N = 10; /* */

5 -
int
{
{
{
{
{
{
{
{
{
{
};

A[N][N] = {
0, 1, 0, 0,
0, 0, 1, 1,
1, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

0,
0,
0,
1,
0,
0,
0,
0,
0,
0,

329

0,
0,
0,
0,
1,
0,
0,
0,
0,
0,

0,
0,
0,
1,
0,
0,
0,
0,
0,
1,

0,
0,
0,
0,
0,
0,
1,
0,
0,
0,

0,
0,
0,
0,
0,
0,
0,
1,
0,
0,

0
0
0
0
0
0
0
0
1
0

},
},
},
},
},
},
},
},
},
}

int used[N];
int postnum[N], count = 0;
/* */
void DFS(int i)
{ int j;
used[i] = 1;
for (j = 0; j < N; j++)
if (!used[j] && A[i][j]) DFS(j);
postnum[i] = count++;
}
/* G */
void backDFS(int i)
{ int j;
printf("%d ", i + 1);
count++;
used[i] = 1;
for (j = 0; j < N; j++)
if (!used[j] && A[j][i]) {
backDFS(j);
}
}
/* */
void strongComponents(void)
{ int i;
for (i = 0; i < N; i++) used[i] = 0;
while (count < N - 1) {
for (i = 0; i < N; i++)
if (!used[i]) DFS(i);
}
for (i = 0; i < N; i++) used[i] = 0;
count = 0;
while (count < N - 1) {
int max = -1, maxv = -1;
for (i = 0; i < N; i++)
if (!used[i] && postnum[i] > max) {
max = postnum[i];
maxv = i;
}
printf("{ ");
backDFS(maxv);
printf("}\n");
}
}

5 -

330

int main(void) {
printf(" :\n");
strongComponents();
}

strconn.c
:
:
{ 1 3 2 6 5 4 }
{ 7 10 9 8 }

:
1. , 1 (n . (n + m)).
: , -
m = n.(n1)/2 . n, (m + n).
2.
? ,
, ,
. ?

5.6.3. .

5.26. .
, ( , )
.
5.27. ,
. , .
5.6.3. 2, 4 6. , 6, : {1, 2, 3, 4, 5} {7}.
1

5.6.3. .
, (n.(m+n)): . , , .
, -.
1. kV , i j (i, jV), k.

5 -

331

2. G(V, E) , T(V, D)
G, . kV
, i, jV , :
1) (k, i)D
2) j k
3) j i T
4) lowest[i] prenum[k], :
prenum[k] , k, prenum
(.. ,
)
lowest[i] :
) prenum[i]
) prenum[w] w , (i, w)E (i, w)D.
) lowest[w] w i D.
2, a :

1)

2)
3)

G. T
, . i prenum[i] prenum
, .
( 2.2.). i, , lowest[i] , 2.
e :
3.1) T, ,
.
3.2) i, T, , i x, lowest[x] prenum[i].

, ,
(n+m). (?) (n2).
-
. T : ,
T, +2
[][].
#include <stdio.h>
#define MAXN 150 /* */
/* */
const unsigned n = 7;
/* */
char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 1, 0, 1, 0 },
{ 0, 0, 1, 0, 1, 1, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 1, 1, 1, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 1, 0 }
};
unsigned prenum[MAXN], lowest[MAXN], cN;
unsigned min(unsigned a, unsigned b) { return (a < b) ? a : b; }

5 -
void DFS(unsigned i)
{ unsigned j;
prenum[i] = ++cN;
for (j = 0; j < n; j++)
if (A[i][j] && !prenum[j]) {
A[i][j] = 2; /* T */
DFS(j);
}
}
/* postorder */
void postOrder(unsigned i)
{ unsigned j;
for (j = 0; j < n; j++)
if (2 == A[i][j]) postOrder(j);
lowest[i] = prenum[i];
for (j = 0; j < n; j++)
if (1 == A[i][j]) lowest[i] = min(lowest[i], prenum[j]);
for (j = 0; j < n; j++)
if (2 == A[i][j]) lowest[i] = min(lowest[i], lowest[j]);
}
void findArticPoints(void)
{ unsigned artPoints[MAXN], i, j, count;
for (i = 0; i < n; i++) {
prenum[i] = 0; lowest[i] = 0; artPoints[i] = 0;
}
cN = 0;
DFS(0);
for (i = 0; i < n; i++)
if (0 == prenum[i]) {
printf(" - \n");
return;
}
postOrder(0);
/* 3.1) */
count = 0;
for (i = 0; i < n; i++)
if (2 == A[0][i]) count++;
if (count > 1) artPoints[0] = 1;
/* 3.2) */
for (i = 1; i < n; i++) {
for (j = 0; j < n; j++)
if (2 == A[i][j] && lowest[j] >= prenum[i]) break;
if (j < n) artPoints[i] = 1;
}
printf(" :\n");
for (i = 0; i < n; i++)
if (artPoints[i]) printf("%u ", i + 1);
printf("\n");
}
int main(void) {
findArticPoints();
return 0;
}

artic.c

332

5 -

333

:
:
2 4 6

:
1 2.

5.6.4. k-
5.28. k- ,
k1 a.
5.29. k- ,
k1 .
G(V, E). :

k, G k- .

k, G k- .
, ,
.
k-
( ) i j , ,
, (?). ,
k
i n1 .
k-
. () k- , k ( )
.
k- :
1) G(V,E) :
G ()
G.
:
iV i1V i2V (i1, i2)E.
(i, j)E (i1, j2)E (i2, j1)E.
2) G k
( ):
) , k-:
G G. (?)
G .
) , k-.
:
1. , G
G.

5 -

334

2. k-
k- .

5.7.
1

1
2

13
3

4
4
16

14

3
12

13

6
1
9

5.7. .

5.7.1.
, ,
.
, , , ,
, . ,
.
, :
G(V,E), V , (i,j) ... i j. f(i,j) . () T(V,D) G
D .
T ().
( 9) , .

-
G(V, E).

1) n , i- i- .
2) ( ).
3) T(V,). T .
4) (n1 ) (i,j) T,
:
f(i, j) - (
)
i j
(i,j) , i j.

5 -

335

, - . ,
i j , "" :
, . ,
"", 4).
n1 (
, ?).
5.7.
():
{1} {2} {3} {4} {5} {6} {7} {8} {9}
, 2), :
(1, 2) = 1; (5, 8) = 1; (7, 6) = 1; (6, 9) = 1; (1, 4) = 2; (2, 3) = 3; (3, 6) = 3;
(3, 4) = 4; (5, 6) = 12; (5, 9) = 13; (2, 5) = 13; (4, 7) = 14; (4, 6) = 14;
(1, 2) ,
1 2. {1, 2} {3} {4} {5} {6} {7} {8} {9}.
(5, 8). : {1, 2} {3} {4} {5, 8} {6}
{7} {9}.
- (7, 6), (6, 9), (1, 4), (2, 3),
(3, 6) : {1, 2, 3, 4, 6, 7, 9}{5, 8}.
(3, 4), 3 4 .
(5, 6),
. (1, 2), (1, 4), (2,
3), (3, 6), (6, 7), (6, 9), (6, 5), (5, 8).
. ,
(n). - . , 2). ( 3.1.9.),
- (m.log2m).
(
4).
( 5.2.).
.
, ,
( ,
).
, ,
(.. ).
( ) (log2n), n1 ,
: (m.log2m + n.log2n).
S[] M
( ). S[i].x, S[i].y, S[i].weight
(S[i].x, S[i].y) S[i].weight. sort(A,0,)
.
:
prev[], prev[i] , i,
( , D!). i ,
prev[i] == 0. , prev[r2] = r1,
r1 r2 , . ,
i, :
root = i;
while (NO_PARENT != prev[root]) root = prev[root];

5 -

336

, , .

i . , i
:
while (i != root) {
savei = i;
i = prev[i];
prev[savei] = root;
}

- -
.
n
- n .
, . n .
5.7.1., lg*n
n, , 0.



n2
n.logn
n.log*n

5.7.1.
n .
, -, 5.7.
#include <stdio.h>
/* */
#define MAXN 200
#define NO_PARENT (unsigned)(-1)
/* */
#define MAXM 2000
const unsigned n = 9; /* */
const unsigned m = 14; /* */
struct arc {
unsigned i, j;
int f;
};
struct
{ 1,
{ 1,
{ 2,
{ 2,
{ 3,
{ 3,
{ 4,
{ 4,

arc S[MAXM] = {
2, 1},
4, 2},
3, 3},
5, 13},
4, 4},
6, 3},
6, 16},
7, 14},

/* */

5 -
{
{
{
{
{
};

5,
5,
5,
6,
6,

6, 12},
8, 1},
9, 13},
7, 1},
9, 1}

int prev[MAXN + 1];


int getRoot(int i)
{ int root, savei;
/* */
root = i;
while (NO_PARENT != prev[root]) root = prev[root];
/* */
while (i != root) {
savei = i;
i = prev[i];
prev[savei] = root;
}
return root;
}
void kruskal(void)
{ int MST = 0;
unsigned i, j;
/* */
sort(S, 0, m);
printf(", :\n");
for (i = 0; i < m; i++) {
int r1 = getRoot(S[i].i);
int r2 = getRoot(S[i].j);
if (r1 != r2) {
printf("(%u,%u) ", S[i].i, S[i].j);
MST += S[i].f;
prev[r2] = r1;
}
}
printf("\n %d.\n", MST);
}
int main(void) {
unsigned i;
for (i = 0; i < n + 1; i++) prev[i] = NO_PARENT;
kruskal();
return 0;
}

kruskal.c
:
, :
(1,2) (5,8) (6,7) (6,9) (1,4) (2,3) (3,6) (5,6)
24.

:
1. , .

337

5 -

338

2. ? , ?
3. ?

-
a .

1) s:
T(H,D), H = {s}, D = .
2) n1 :
2.1) (i, j), :

iH, jV\H;

f(i, j) .
2.2) j H (i, j) D.
5.7.:
, 1. , , H, (1, 2).
2 H, (1,2) D. ,
H , H, (1, 4). (2, 3), (3,
6), (6, 7), (6, 9), (6, 5) (5, 8), .
. , , 2.1). ,
,
H, (n3). n-
, T[] -
( H) , ..
:

, s, :
o [j] = A[s][j], j = 1,2,..., n., (s, j)
o [j] = MAX_VALUE, .
:
o j, T[j] .
o kH T[k] = min(T[k], A[j][k]).

, .
#include <stdio.h>
/* */
#define MAXN 150
#define MAX_VALUE 10000
/* */
const unsigned n = 9;
/* */
const int A[MAXN][MAXN] = {
{ 0, 1, 0, 2, 0, 0, 0, 0, 0
{ 1, 0, 3, 0, 13, 0, 0, 0, 0
{ 0, 3, 0, 4, 0, 3, 0, 0, 0
{ 2, 0, 4, 0, 0, 16, 14, 0, 0
{ 0, 13, 0, 0, 0, 12, 0, 1, 13
{ 0, 0, 3, 16, 12, 0, 1, 0, 1

},
},
},
},
},
},

5 -
{ 0,
{ 0,
{ 0,
};

0, 0, 14, 0,
0, 0, 0, 1,
0, 0, 0, 13,

339
1,
0,
1,

0, 0,
0, 0,
0, 0,

0 },
0 },
0 }

char used[MAXN];
unsigned prev[MAXN];
int T[MAXN];
void prim(void)
{ int MST = 0; /* */
unsigned i, k;
/* */
for (i = 0; i < n; i++) { used[i] = 0; prev[i] = 0; }
used[0] = 1; /* */
for (i = 0; i < n; i++)
T[i] = (A[0][i]) ? A[0][i] : MAX_VALUE;
for (k = 0; k < n - 1; k++) {
/* */
int minDist = MAX_VALUE, j = -1;
for (i = 0; i < n; i++)
if (!used[i])
if (T[i] < minDist) {
minDist = T[i];
j = i;
}
used[j] = 1;
printf("(%u,%u) ", prev[j] + 1, j + 1);
MST += minDist;
for (i = 0; i < n; i++)
if (!used[i] && A[j][i]) {
if (T[i] > A[j][i]) {
T[i] = A[j][i];
/*
*/
prev[i] = j;
}
}
}
printf("\n %d.\n", MST);
printf("\n");
}
int main(void) {
prim();
return 0;
}

prim.c
:
(1,2) (1,4) (2,3) (3,6) (6,7) (6,9) (6,5) (5,8)
24.

,
(?).

5 -

340

- (, [Cormen, Leiserson, Rivest-1997]),


(m + n.log2n).
, .. mO(n), - , (m.(m, n)) (m.log2( (m,n))),
([Cormen, Leiserson, Rivest-1997][Fredman,Tarjan-1987]):
m
m, n min i, : log(log(..
. log( n)...))

n
i

:
1. , .
2. ?
3. ?
4. , [1, n]?

-
.
. 5.30. G(V, E). k, k n
Tk (Vk , D) , k , :

Vk V.

D.

, D, .
:

, k . ,
k1 (.. k1 ). n
( ), - .
.
:
1. .
2. .

5.7.2.
: G(V, E) ,
(i, j), i, jV.
G'(V', E') G.
. ,
.
1: n , , .
, .
2: n , , .
, .

5 -

341

. (
, -).
3
1

4
5

5.7.2. .
5.30. G(V, E). H, HV ( ), .
5.31.
G.
,
. , 5.7.2.
{7, 8, 2}, {3, 1}, {7, 8, 2, 5}. 4.

-
5.32. H , H, H
.
5.7.2 H1 = {7, 8, 2, 5},
H2 = {7, 8, 2} , H1.
{1, 3, 7} {4, 6}.

G(V, E).
:
1) S .
2) iV, iST.
3) i T. S , i.
4) 2) 3), ,
S, T, .. ST = V. T
.
, . 2) ,
, .. S T. maxSubSet(last):
maxSubSet(last) {
if (ST = V) {
____;
return;
}
for (__i | iV, iS, iT, i > last) {
_i__T;
_ _S___i_;
maxSubSet(i);

5 -

342

_i__T;
_S____;
}
}

last , . i, i > last. ,


( {1, 3, 7} {1, 7, 3} ..).
. ,
.
#include <stdio.h>
/*
#define MAXN 200
/* */
const unsigned n = 8;
/*
const char A[MAXN][MAXN] =
{ 0, 1, 0, 0, 0, 1, 0, 1
{ 1, 0, 1, 0, 0, 1, 0, 0
{ 0, 1, 0, 1, 1, 0, 0, 0
{ 0, 0, 1, 0, 1, 0, 1, 0
{ 0, 0, 1, 1, 0, 1, 0, 0
{ 1, 1, 0, 0, 1, 0, 1, 1
{ 0, 0, 0, 1, 0, 1, 0, 0
{ 1, 0, 0, 0, 0, 1, 0, 0
unsigned S[MAXN], T[MAXN],

*/

*/
{
},
},
},
},
},
},
},
} };
sN, tN;

void print(void)
{ unsigned i;
printf("{ ");
for (i = 0; i < n; i++)
if (T[i]) printf("%u ", i + 1);
printf("} \n");
}
void maxSubSet(unsigned last)
{ unsigned i, j;
if (sN + tN == n) {
print();
return;
}
for (i = last; i < n; i++) {
if (!S[i] && !T[i]) {
for (j = 0; j < n; j++)
if (A[i][j] && !S[j]) {
S[j] = last+1; sN++;
}
T[i] = 1; tN++;
maxSubSet(i+1);
/* */
T[i] = 0; tN--;
for (j = 0; j < n; j++)
if (S[j] == last+1) { S[j] = 0; sN--; }
}
}
}
int main(void) {

5 -

343

unsigned i;
printf(" :\n");
sN = tN = 0;
for (i = 0; i < n; i++) S[i] = T[i] = 0;
maxSubSet(0);
return 0;
}

maxindep.c
:
:
{ 1 3 7 }
{ 1 4 }
{ 1 5 7 }
{ 2 4 8 }
{ 2 5 7 8 }
{ 3 6 }
{ 3 7 8 }
{ 4 6 }

:
1. , .
2. 1.

5.7.3.
5.33. G(V, E).
S, :
SV
, S, S.
5.34. ,
.
, .
: , ,
. 5.7.3. A, B, C,
D, E, , , 1 .

A
1
1
0
1
0
0
0

B
0
1
1
0
1
0
0

C
1
0
0
0
1
0
1

D
1
0
0
1
0
1
0

E
0
0
0
0
1
1
0

5.7.3. .
,
, . , B, C D, .

5 -

344

, -, , ( .
,
[-1996].).
.
p1, p2, , pk
, p = min{p1, p2, , pk } .
1
2

5.7.3. .
5.7.3. {1, 4}, {1, 4, 6}, {3, 5, 6} .,
{1, 4} {3, 5, 6} . {1, 4, 6} ,
( {1, 4} ). 2.
5.35. e G(V, E) T, TV.
T P(T), T ,
T.

T . T,
:

iT, P(T\{i}) P(T).


P(T) V, .
, T .
- , ok()
T. T
:
void findMinDom(int last) {
if (P(T) == V) {
_____;
return;
}
for (__i__, i >= last) {
T = T{i};
if (ok()) findMinDom(i+1);
T = T\{i};
}
}

:
#include <stdio.h>
/* */
#define MAXN 200

5 -

/* */
const unsigned n = 6;
/* */
const char A[MAXN][MAXN] = {
{ 0, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0 }
};
unsigned cover[MAXN];
char T[MAXN];
void printSet(void)
{ unsigned i;
printf("{ ");
for (i = 0; i < n; i++)
if (T[i])
printf("%u ", i + 1);
printf("}\n");
}
char ok(void)
{ unsigned i, j;
for (i = 0; i < n; i++) if (T[i]) {
/* i */
if (0 == cover[i]) continue;
for (j = 0; j < n; j++) if (cover[j])
if (!(cover[j] - A[i][j]) && !T[j])
break; /* */
if (j == n) return 0;
}
return 1;
}
void findMinDom(unsigned last)
{ unsigned i, j;
/* */
for (i = 0; i < n; i++)
if (!cover[i] && !T[i]) break;
if (i == n) { printSet(); return; }
/* - */
for (i = last; i < n; i++) {
T[i] = 1;
for (j = 0; j < n; j++) if (A[i][j]) cover[j]++;
if (ok()) findMinDom(i + 1);
for (j = 0; j < n; j++) if (A[i][j]) cover[j]--;
T[i] = 0;
}
}
int main(void) {
unsigned i;
printf(" : \n");
for (i = 0; i < n; i++) { cover[i] = 0; T[i] = 0; }
findMinDom(0);
return 0;

345

5 -

346

mindom.c
:
:
{ 1 2 6 }
{ 1 3 6 }
{ 1 4 }
{ 3 5 6 }

:
,
.

5.7.4.
: n .
() ,
.
5.7.4. . {4, 7, 9}. : {5, 7,
9}, {7, 8, 9} .
5.36. G(V, E). ( )
V , :

T , , .
1. e , :
1) , , .
2) i, .
2.
, (.. ).
( 1 2) , ,
.
5

7
2

8
4

5.7.4. .

, . base[],
base[i] == 1, i , base[i] == 0, .
. k, base[k] == 1.
i (i k), , base[i] = 0.
, , .

5 -

347

(n+m), -
(?). :
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 9;
/* */
const char A[MAXN][MAXN] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 }
};
char used[MAXN], base[MAXN];
void DFS(unsigned i)
{ unsigned k;
used[i] = 1;
for (k = 0; k < n; k++)
if (A[i][k] && !used[k]) {
base[k] = 0;
DFS(k);
}
}
void solve(void) {
unsigned i, j;
for (i = 0; i < n; i++) base[i] = 1;
for (i = 0; i < n; i++)
if (base[i]) {
for (j = 0; j < n; j++) used[j] = 0;
DFS(i);
}
}
void print() {
unsigned i, count = 0;
printf(", , :\n");
for (i = 0; i < n; i++)
if (base[i]) { printf("%u ", i + 1); count++; }
printf("\n : %u\n", count);
}
int main(void) {
solve();
print();
return 0;
}

v-base.c
:

5 -

348

, , :
4 7 9
: 3

:
1. 1, 2.
2. , .

5.7.5. ,

, . ,
, . , ( , ,
..) , - . - .
p ( ),
- S(i) i - .
5.37. G(V, E).
So(i) iV d(i, j), jV, d(i, j)
i j. T.. - - i. , S t(i) i jV i.
5.38. iV, po = So(i)
. i G, po
. , j, pt = St(j) .
j G, pt .
5.39. Sot(i) d(i, j)+ d(j, i), jV.
v , Sot(v) . v - ( ), Sot(v) - ( )
.
, .
: , S
, S - .
(p- p- ), . ( 5.7.5.).
1

5
3
4

1
2
3
1
0
1
2
2
3
0
1
3
4
3
0
4
3
2
2
5
2
1
1
6
1
2
3
: 2

4
3
2
1
0
2
4

5
2
1
2
1
0
3

{d ( 2, i ) d (i ,2) | i V } 4
= i max
1, 2 ,..., n

6
3
2
3
2
1
0

5 -

349

5.7.5. ( 1).
- ( 5.7.5.) . , -. (n3). (?)
-
A[][], n.
.
#include <stdio.h>
/* */
#define MAXN 150
#define MAX_VALUE 10000
/* */
const unsigned n = 6;
/* */
int A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0 }
};
/* */
void floyd(void)
{ unsigned i, j, k;
/* 0 MAX_VALUE */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (A[i][j] == 0)
A[i][j] = MAX_VALUE;
/* */
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (A[i][j] > (A[i][k] + A[k][j]))
A[i][j] = A[i][k] + A[k][j];
for (i = 0; i < n; i++)
A[i][i] = 0;
}
void findCenter(void)
{ unsigned i, j, center;
int max, min;
min = MAX_VALUE;
/* Sot(Xi) = max { Vj [d(Xi, Xj)+d[Xj,Xi])] }, X*
* Sot(X*)
*/
for (i = 0; i < n; i++) {
max = A[i][0] + A[0][i];
for (j = 0; j < n; j++)
if ((i != j) && ((A[i][j] + A[j][i]) > max))
max = (A[i][j] + A[j][i]);

5 -

350

if (max < min) {


min = max; center = i;
}
}
printf(" %u\n", center + 1);
printf(" %u\n", min);
}
int main(void) {
floyd();
findCenter();
return 0;
}

a-center.c
:
2
4

:
1. .
2. ,
.

- p- p-
p
. - i -
. d(i,j) i j.
5.40. G(V,E) Q = {vi1, vi2, , vip |
vik V}. :
S(v,Q) = min { d(vk , v) + d(v, vk ) | vk Q}, vV
S(Q) = max { S(v,Q) | vV }
S(Q), p- Q V,
p- .
- , :
5.41. G(V,E) Q = {vi1,vi2,,vip |
vik V}. :
S(v,Q) = min { d(vk , v) | vk Q}, vV
S(Q) = max { S(v,Q) | vV }
S(Q), p- Q V,
p- .
p-
. , . : p- Q, QV, S - . O
( C np ) , S.

5 -

351

,
. [][],
( p- Q
V) - .
, .
5.7.5.
1
1

3
3

2
5

6
2

1
2
3
4
5
6
7

1
0
1
5
6
2
10
12

2
1
0
4
7
3
9
11

3
5
4
0
3
7
5
7

4
6
7
3
0
4
8
8

5
2
3
7
4
0
12
12

6
10
9
5
8
12
0
2

7
12
11
7
8
12
2
0

5.7.5. p-.
3-, .. p = 3 , 5.7.5. {2, 3, 6}:
S = max { min { [i][2], [i][3], [i][6] | i = 1,2,...,7} = max { 1, 0, 0, 3, 3, 0, 2 } = 3.
-, , , {2, 3, 6}
, S 3- .
! {1, 3, 6} 3- S = 3.
, .
, .
#include <stdio.h>
/* */
#define MAXN 150
#define MAX_VALUE 10000
/* */
const unsigned n = 7;
const unsigned p = 3; /* p- */
/*
int A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 2, 0,
{ 1, 0, 4, 0, 0, 0,
{ 0, 4, 0, 3, 0, 5,
{ 0, 0, 3, 0, 4, 0,
{ 2, 0, 0, 4, 0, 0,
{ 0, 0, 5, 0, 0, 0,
{ 0, 0, 0, 8, 0, 2,
};

*/
0
0
0
8
0
2
0

},
},
},
},
},
},
}

unsigned center[MAXN], pCenter[MAXN], pRadius;


/* */
void floyd(void)
{ unsigned i, j, k;
/* 0 MAX_VALUE */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)

5 -

352

if (A[i][j] == 0) A[i][j] = MAX_VALUE;


/* */
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (A[i][j] > (A[i][k] + A[k][j]))
A[i][j] = A[i][k] + A[k][j];
for (i = 0; i < n; i++)
A[i][i] = 0;
}
/* S */
void checkSol(void)
{ unsigned i, j, cRadius = 0;
for (j = 0; j < n; j++) {
int bT = MAX_VALUE;
for (i = 0; i < p; i++)
if (A[center[i]][j] < bT) bT = A[center[i]][j];
if (cRadius < bT) cRadius = bT;
}
if (cRadius < pRadius) {
pRadius = cRadius;
for (i = 0; i < p; i++) pCenter[i] = center[i];
}
}
/* C(n,p) p- G */
void generate(unsigned k, unsigned last)
{ unsigned i;
for (i = last; i < n - p + k; i++) {
center[k] = i;
if (k == p)
checkSol();
else
generate(k + 1, i + 1);
}
}
/* p- p- */
void printPCenter(void)
{ unsigned i;
printf("%u- : {", p);
for (i = 0; i < p; i++) printf("%d ", pCenter[i] + 1);
printf("}\n");
printf("%u- %u\n", p, pRadius);
}
int main(void) {
floyd();
pRadius = MAX_VALUE;
generate(0, 0);
printPCenter();
return 0;
}

p-center.c

5 -

353

:
3- : {1 3 6 }
3- 3

:
1. , {2,3,6} p- 5.7.5.
2. p-.
3. , p-.
4. - ?
( : ?), ( )?

5.7.6. .
( . matching)
, .
5.42. G(V,E) E'E,
E'. ,
E', , ,
.
, .
5.43. E' k ,
E'' l k l.
5.44. E e G. G
M, ,
M. M ,
M.

( ).
.
, . (?) ,
: M , P
. M P,
M P. :
, .
:
5.45. G(V, E) ,
V=V'V'', V'V''=, (i, j)E iV' jV".
: .
1
.
G(V, E) V=V'V'',
V'V''=. , , :

V' .

V'' .

c(i, j) = 1.

5 -

354

2
( -) . (n),
(?). (n.(m+1)) = (n.m). - , ( n .m)
[Hopcroft-Karp-1973], - [Micali,Vazirani-1980].
:
1. , ,
.
2. , .
3.
.
4. 1 2.

5.8.
5.8.1. .
, ,
, , ,
.
5.46. r-
{c1, c2, , cr} .
r- .
5.47. G(V,E) r-,
r- , . - r, r-, G (
G) V(G). , - r ,
r- , ,
, G E(G).
:
1: , e , .
, ,
?
G, . ....
, .
V(G), .
2: n " " . , , .
E(G), .

5 -

355

-

. , V(G)
. (
, ):

V(G) 2 G .
V(G) 3 G .
(G) dm(G), dm(G) G.
V(G) n / V(G'), n G, G' G.
V(G) n2 / (n2 2m), n , a m G.

-
V(G)
1)
V(G) Vmin.
2)
for (r = Vmin ; r < n; r++) {
if (G r-) { ___3 }

3)

r .

r-. NP- 6.3.2.:


, ,
, .
, , .
.
, : ,
, .
- [Christofides-1975][Korman-1979].
, ,
, , . ,
r- ( ),
. ,
, . 9.
:
V(G).

5.8.2.
5.48. ...
( ) , .
, , .
( , ).
, ,
, .

5 -

356

1933
.
5.8. ,
:
G(V, E) G'(V, E'), i, jV (i,
j) ' E. G' G.
(i, j)E i, jV, . n
Kn (K5 5.8.2.).

5.8.2. 5.

5.8.2. 3,3.

5.49. G(V, E) V = V'V'', V'V'' = ,


iV' jV" (i, j)E, , G(V = V'V'', E) .
V' m, V'' n,
Km,n. 5.8.2. e K3,3.
5.50. G(V, E) G'(V', E'),
G 2
.
5.51. G' G'' ( G'G"), G' G", .
. () ... , K5 K3,3.
. ( ) - 4.
,
, .
1850. - , 1976 .
. . . 2000 , 1000 .
, .
[Chiba,Nishizeki,Abe,Ozawa-1985],
, .
.
:
, ..
- 5, , ?

5 -

357

5.9.
5.9.1.
5.1.
5.13. 2.2.
5.2.
5.2.6.
5.3.
5.3.1. .
, , ?
5.4.
5.3.1. , , , ?
5.5.
5.3.2.
5.6.
BFS() - 5.4.1. ,
ev.
5.7.

( 5.4.1.)?
5.8.

( 5.4.1.)? ?
5.9.

(BFS), 5.4.1. ?
?
5.10.
5.4.2.
5.11.

5.4.2.
5.12.
- 5.4.2.
5.13.
- - ( 5.4.2.) n-2 ,
n n1?

5 -

358

5.14.
, - ( 5.4.2.)
(i, j) D[i] > D[j] + A[j][i], .
5.15.
, : ,
- (i, j),
D[i] > D[j] + A[j][i]? ( 5.4.2.)
5.16.
(i,j) ,
( 5.4.2.).
5.17.
(i,j) ,
( 5.4.2.).
5.18.
( 1 , 5.4.2.).
5.19.
( 2
, 5.4.2.).
5.20.
p ( 3
, 5.4.2.).
5.21.
- ( 5.4.2.).
5.22.

d[], pred[] (
5.4.2.)?
5.23.
5.4.2.
5.24.
( 5.2.4.).
5.25.
, ( 5.2.4.) .
5.26.
, :


5.27.
- ( 5.2.4.),
, .

5 -

359

5.28.
i j,
- 5.2.4.
- i j.
5.29.
, - ( 5.2.4.) ?
? ? .
5.30.
5.4.3. (/ ) ?
5.31.
5.4.3. (/ ) ? ?
5.32.
5.4.3. (m.(m+n)),
,
(n4). ? ,
(m+n), h
, ..
((m+n).h). , -
, .. ((m+n).n).
,
((m+n).h)?
, ? , h O(log2n)?
5.33.

( 5.4.3.).
5.34.
. ,
, ( 5.4.3.).
5.35.
,
( 5.4.4.) ( ).
5.36.
/ ( 5.4.5.).
5.37.
( 5.4.4.)
( 5.4.5.). - ?
5.38.
, , .
( 5.4.6.)

5 -

360

5.39.
, -
, ( 5.4.6.)
5.40.
, -
,
( 5.4.6.)
5.41.
( 5.5.1.).
5.42.
, ( 5.5.1.).
, .
5.43.
, , ( 5.5.2.).
5.44.
, E'E , .. ( )
?
( 5.5.3.)?
5.45.
( 5.5.4.) ,
- (n3)?
5.46.
5.25.
5.47.
, 2 1 5.5.5.
, .
5.48.

5.5.6.
5.49.
1 5.5.7.
5.50.
G(V, E). G(V, E), :

EE

Z, G.

E .
- , ?
5.51.
5.5.8., ?
5.52.
5.5.8., ?

5 -

361

5.53.
, 5.5.8. .
5.54.
5.5.8.
.
5.55.

( 5.5.8.) (m+n)? -?
5.56.

( 5.6.1.).
5.57.
, 1 5.6.2. (n . (n + m)).
: , -
m = n.(n1)/2 . n, (m + n).
5.58.

( 5.6.2.)? ,
, ,
. ?
5.59.
1 2 5.6.3.
5.60.
, G
G ( 5.6.4.).
5.61.
k- k- ( 5.6.4.).
5.62.
, ( 5.7.1.).
5.63.
( 5.7.1.)? , ?
5.64.
( 5.7.1.)?
5.65.
, ( 5.7.1.).
5.66.
( 5.7.1.)?
5.67.
( 5.7.1.)?

5 -

362

5.68.
4. (
5.7.1.) , [1, n]?
5.69.
( 5.7.1.).
5.70.

( 5.7.1.).
5.71.
, 5.7.2.
.
5.72.
1, 5.7.2.
5.73.
, 5.7.3. .
5.74.
1, 2 3 5.7.4.
5.75.
, 5.7.4. .
5.76.
( 5.7.5.).
5.77.
5.7.5. ,
.
5.78.
, {2,3,6} p- 5.7.5.
5.79.
p- ( 5.7.5.).
5.80.
5.7.5. , p-.
5.81.
5.7.5. ? ( : ?), ( )?
5.82.
, ,
( 5.7.6.).
5.83.
,
( 5.7.6.).

5 -

363

5.84.

( 5.7.6.).
5.85.
1 2 5.7.6.
5.86.
V(G) 5.8.1.
5.87.
( 5.8.2.), ..
- 5, , ?

5.9.2.
, ,
.
5.88. , Duke programming contest, 1992, problem f.
( . Chinese Postman Problem) e ).
,
. ( ,
).
5.89. Duke programming contest, 1993, problem g.
i < j. ,
, . , x < y x < z : x y z x z y.
5.90. Duke programming contest, 1993, problem h.
, . ,
.
(, ). 1.
5.91. ACM Regional contest, New Zealand, 1991, problem A
G(V, E). , B-
vV - v
. B- B- .

G
H

E
C

5.9.2. B- .

5 -

364

. 5.9.2. (A, B, C, D, E, H, F, G) (A,


B, C, D, G, F, H, E) B- : 6, 6, 1, 4, 1, 1, 6, 6 5, 3, 1,
4, 3, 5, 1, 4 , B- 6 , 5 .
, , B-
.
5.92.
.
, 3 .
: , . i j
, (
-
. ,
). :
1. (i, j) :

(i, j)

i j.
Lij.
Lij .
(m.n.log2n).
2. :

d(i, j) i j.

f(i, j) (i, j).


d(i,k) + f(k,j) +
d(j,i), i, j k, i k
j i.
1.
2.
5.93. k
k. ,
G(V,E) G, k .
, k = n ,
NP- ( 6), n, k .
- n , , k e , ?
5.94.
52. G(V, E) v : VR+,
. V , :

T .
.
, , , - ( 5.4.2).

5 -

365

5.95.
. : 1, 2, , n. i1, i2,
, ik (i1 < i2 < ...< ik ), ij i(j+1) j = 1, 2,, k1, S =
a .

ij
j 1, 2 ,...,k

5.96.
n , (xi, yi, zi).
, .
: , , .
5.97.
,
?
5.98.
.
n1 0.
5.99.
n m . (m+n)
.
: .
5.100.
- ?
5.101.
G(V, E) n (n 11) . G
.
: , G ,
G.
5.102. -5/1994
. . ,
.
: . , .
5.103. d-
A[][] nn, . .
.
5.104. ( 1995, 1, 1)
n (2 n 200) 1 100 n1 ,
( ). S (), .
, S, . , .
S,
.

5 -

366

[Infoman]: G(V, E) . S k (2 k n1)


. i- Ti. ,
S , T = max{Ti}, i = 1,2,...,k .
- ,
(n)?
5.105. ()
, s t. H () ,
H (), s t .
5.106.
,
() ?
:
. , n
, .
5.107.
.
, .
5.108. 2n
n. ,
1 n.
: , . , .
5.109.
, .
, , - (n3)?
5.110.
0 X :
(sx,sy) (tx,ty). , .. , :

0.
"", ..
.
.

: .. ( ). :
1) 1. i = 1.
2) , i. (.. 0) i+1.
3) 2 ,
( i+1). i
2).

5 -

367

X
X
X
X
X
X
X
X

X
1
2
3
4
5
6
X

X
2
X
4
X
6
7
X

X
3
X
5
6
7
8
X

X
4
X
X
7
X
9
X

X
5
6
8
8
X
X
X

X
6
7
X
X
X
X
X

X
X
X
X
X
X
X
X

5.9.2. .
, , , .
.

6
. NP-

... ,
...
~ -, .
,
( ). ,
. ,
,
.

6.1.
, , .
.
- : .

6.1.1.
(.. ,
).
NP-
NP ( . non-deterministic polynomial time) . NP,
,
. , NP- ,
, "" ,
( 2 6.1.4.).
P-
,
( P . polynomial). (
NP) : ,
. ,
, - .
( log-),
. ( 1 6.1.4.).

, .
, , -
, - .

6 - . NP-

370

6.1.2.
, , .
. : P-space (,
), exp-space ( ) . ( 3 6.1.4.).
, ,
. , (n) , (n) [-1996].

6.1.3.
, [-1996],
, . -
( 4 6.1.4.).

6.1.4.
( )
6.1.4. NP- , 6.2. , . P NP
P NP. , - 6.1.4. .

P
NP

log

NP
NP-

6.1.4. ( ).
, .
1.
,
: (
, , , ,
, ), (
(log2n)), ,
.
2. NP-
NP-: n. n, q (1 < q < n).
q', p'
, n = p'.q',
.

6 - . NP-

371

:
G(V,E), i,jV k.
: ( ) i j
k.
NP: , (
) k. ,
P.
- , ,
NP- .
, .
3.
"" ( ,
..) . ,
, "" , .
" ", 1997 Deep Blue, IBM, . 1996 . Deep Blue
, ( 6 ). -, 1997 .
3,5:2,5 (2 , 1 3 ),
17 - $100,000 ,
. ,
, ,
: Deep Blue , ,
. [Russell,Norvig1995][Loviglio-1997]
- ,
. 1992 . Chinook,
, US Open, ,
21,5:18,5. 40
(!) 3 . Chinook
. -, 1994 . Chinook ,
,
.
.
? : ,
, 20 ,
..
.
exp-space,
. ?
88. - ,
( , ,
65^32 ?). ,
: - 150 . ,
, , , :
() .

6 - . NP-

372

, - ( 6.5.3.),
, .
- ( 8 ) ,
"" (
., 6.5.4.) - .
4.
: x y vu. x y,
. : , ( ) v,
u ( vu).
, , .
: ,
, , "" ,
, . , , ( ). : ,
, . , :
int main() {
unsigned a, b, c, i, x;
for (x = 3;;) {
for (a = 1; a <= x; a++)
for (b = 1; b <= x; b++)
for (c = 1; c <= x; c++)
for (i = 3; i< = x; i++)
if (pow(a, i) + pow(b, i) == pow(c, i))
exit(0);
x++;
}
return 0;
}

an + bn = cn,
a, b, c, n n > 2. ,
. ( ), ,

, . , ,

.
-. (
[-1996]) .
5.

: [MathWorld-a]:
M33. n ,
M n, , 0.

6 - . NP-

373

:
1. .
2. , , .
3. :
n .
n, -
q (q > 1, q < n).

6.2. NP-
, - P
NP. ,
, ?
, . , , . .. , NP
P. , NP-,
. NP- NP-,
( ), NP
NP- . NP- , P,
NP ( NP, NP-.). NP- -

( ,
).
6.1. , A B A B,
,
, B,
.
, B P A B, , P.
: ( 5.4.4.)
. . , . ,
2:
for (__(i,j)__) {
if (_____n-1___i__j) {
return 1; /* : + (i,j)*/
}
}
return 0;

m. m - (m).
-, , -
. -
, , .
6.2. NP- A NP- (. NP-complete),
, B NP , B A.

6 - . NP-

374

. () , NP-.
, NP-
[-1996] ( 6.3.1.).
, NP-. ( 6.6.)
70 NP- . ,
. , , : NP-, NP
. , P NP.
,
(P, NP, NP-) , .. .
( ):
1. .
2. , - k.
, , :
3. .
: NP-.
6.3. A ( )
NP-, , B NP , B A.
, , NP- NP NP-. NP- NP-
: NP- NP- , .
NP- - NP-.
, 2 - (
), (
3).
:
1. 6.2. , NP- A
B, B NP-.
2. , NP , (, NP ).
3. " n, q (q > 1, q < n)" NP.
NP-?

6.3.
P NP (- P NP,
P NP, P NP - ), ,
, NP- ( NP-)
, .
.

6 - . NP-

375

( . backtracking) ,
(). () .
- ,
. ,
,
. :
void ( i)
{ if (i > n) ____;
else
/* */
for (k = 1; k <= n; k++)
if (k-___) {
__;
(i+1);
__;
}
}

. ,
, :
1)
2)

sV
.
, v,
.
.
, , :
2.1) v s, ,
.
2.2) ( ), :
. , , , . , ,
.

2.1) , , 2.2), .
, NP-
.
:
(,
)?

6 - . NP-

376

6.3.1.
"" NP-
. 6.2.,
NP- .
.
X1,X2,...,Xn. X 1 , X 2,..., X n (. . Xi , X i ).
,
"" () "" (), 0 1
.
( -).
, , : (A B). A B A.B
AB.
6.3.1.
.
x
y
xy
xy
1
1
1
1
1
0
0
1
0
1
0
1
0
0
0
0
6.3.1. .
6.4. X1,X2,...,Xn ,
"" "" X1,X2,...,Xn,
.
: .
, ( X 2 X2 X1) X 3 X1 = 1, X2 = 0, X3 = 0
X1 = 1, X2 = 1, X3 = 0. , , NP-: , , , ,
.
, .
6.5. 0 1,
.
6.6. , "".
6.7. , ,
"", .

A (B C) = (A B) (A C)
.
:
A B A B
A B A B

6 - . NP-

377

, :
(X1 X4) ( X 1 X2) (X1 X 3 ) ( X 2 X3 X 4) ( X 1 X 2 X 3 )
,
: 2n
, (2n). , :
i = 1.
1) i- (i+1)-
( ). -
, ( ),
.
2) , .
,
, .
()
1 n, Xi i. values[] (0 1), . true()
values[] . : , ( "").
,
(
"").
-,
assign(unsigned i), (i = n) true(), (. . ).
:
#include <stdio.h>
#define MAXN 100 /* */
#define MAXK 100 /* */
const unsigned n = 4;
const unsigned k = 5;

/* */
/* */

const int expr[][MAXK] = {


{ 1, 4 },
{ -1, 2 },
{ 1, -3 },
{ -2, 3, -4 },
{ -1, -2, -3 }
};
int values[MAXN];
void printAssignment(void)
{ unsigned i;
printf(" : ");
for (i = 0; i < n; i++) printf("X%u=%u ", i+1, values[i]);
printf("\n");
}

6 - . NP-

378

/* */
int true(void)
{ unsigned i;
for (i = 0; i < k; i++) {
unsigned j = 0;
char ok = 0;
while (expr[i][j] != 0) {
int p = expr[i][j];
if ((p > 0) && (1 == values[p-1])) { ok = 1; break; }
if ((p < 0) && (0 == values[-p-1])) { ok = 1; break; }
j++;
}
if (!ok) return 0;
}
return 1;
}
/* */
void assign(unsigned i)
{ if (i == n) {
if (true()) printAssignment();
return;
}
values[i] = 1; assign(i + 1);
values[i] = 0; assign(i + 1);
}
int main(void) {
assign(0);
return 0;
}

bool.c
:
: X1=1 X2=1 X3=0 X4=0
: X1=0 X2=0 X3=0 X4=1

3 :
6.3.1. - ,
X1(X2X3).

X1=0
X2=0
X3=0

X3=1

X1=1

X2=1
X3=0

X2=0
X3=1

X3=0

X2=1

X3=1

X3=0

X3=1

6.3.1. .
NP- ( ),
( ),
. . ,

6 - . NP-

379

X1(X2X3) X1 = 0 ,
, , X2 X3.
-,
.
:
1)

2)

true() t, ,
t . ,
, - t, ,

n-t . ,
,
.
true() . , ,
, , .
#include <stdio.h>
/* */
#define MAXN 100
/* */
#define MAXK 100
const unsigned n = 4;
const unsigned k = 5;

/* */
/* */

const int expr[][MAXK] = {


{ 1, 4 },
{ -1, 2 },
{ 1, -3 },
{ -2, 3, -4 },
{ -1, -2, -3 }
};
int values[MAXN];
void printAssign(void)
{ unsigned i;
printf(" : ");
for (i = 0; i < n; i++) printf("X%d=%d ", i + 1, values[i]);
printf("\n");
}
/* */
int true(int t)
{ unsigned i;
for (i = 0; i < k; i++) {
unsigned j = 0;
char ok = 0;
while (expr[i][j] != 0) {
int p = expr[i][j];
if ((p > t) || (-p > t)) { ok = 1; break; }
if ((p > 0) && (1 == values[p-1])) { ok = 1; break; }
if ((p < 0) && (0 == values[-p-1])) { ok = 1; break; }

6 - . NP-

380

j++;
}
if (!ok) return 0;
}
return 1;
}
/* */
void assign(unsigned i)
{ if (!true(i)) return;
if (i == n) {
printAssign();
return;
}
values[i] = 1; assign(i + 1);
values[i] = 0; assign(i + 1);
}
int main(void) {
assign(0);
return 0;
}

boolcut.c
:
1. .
2. ( X 2 X3 X1) X2 ( X 1 X 3 )?
3. A (B C) = (A B) (A C),
.
4. .
5. A B A B .
6. .
, .
7. , , {, } {,
} {, , }.
8. , {, } {, , }?

6.3.2.
5.8.1. .
NP- , . NP- NP-
r- :
n. r (1 r n)
r .
r- .
, r-:

: i = 1.
i: i-
(i+1)- , i-
(i+1)- ..

6 - . NP-

381

(. . i = n), .
, ,
.

, :
n n = (nn). , r
r 1
: ,
, .
, i-
. , ,
(i+1)- , i- .
i- r- , . , i = 1 ,
r- ( ).
. A[][],
col[], ,
i- , nextCol(unsigned i).
6.3.2.
1

2
1

1
3

6.3.2. r- .
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 5;
/* */
const char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1 },
{ 0, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 1 },
{ 1, 1, 0, 1, 0 }};
unsigned col[MAXN], maxCol, count = 0;
char foundSol = 0;
void showSol(void)
{ unsigned i;
count++;
printf(" : \n");
for (i = 0; i < n; i++)
printf(" %u - %u \n", i + 1, col[i]);
}
void nextCol(unsigned i)
{ unsigned k, j, success;

6 - . NP-

382

if (i == n) { showSol(); return; }
for (k = 1; k <= maxCol; k++) {
col[i] = k;
success = 1;
for (j = 0; j < n; j++)
if (1 == A[i][j] && col[j] == col[i]) {
success = 0;
break;
}
if (success) nextCol(i + 1);
col[i] = 0;
}
}
int main(void) {
unsigned i;
for (maxCol = 1; maxCol <= n; maxCol++) {
for (i = 0; i < n; i++) col[i] = 0;
nextCol(0);
if (count) break;
}
printf(" %u : %u \n",maxCol,count);
return 0;
}

colorm2.c
:

1 - 1
2 - 2
3 - 3
4 - 1
5 - 3

1 - 1
2 - 3
3 - 2
4 - 1
5 - 2

1 - 2
2 - 1
3 - 3
4 - 2
5 - 3

1 - 2
2 - 3
3 - 1
4 - 2
5 - 1

1 - 3
2 - 1
3 - 2
4 - 3
5 - 2

6 - . NP-

383

:
1 - 3
2 - 2
3 - 1
4 - 3
5 - 1
3 : 6

:
1. , , .. r (1 r n)
r .
2. .
3. .

6.3.3. -
-
(
, ). - .
. j
, .
j . ,
, . ,
- , , :
void (i) {
if (____) { _ ; }
for (__k__i)
if ((___k) &&
(k_______))
{
__k__;
________;
(i+1);
/* */
_k____;
__k__;
________;
}
}
}

. .
, ( ). ..
. - addVertex() .
A[][], a 6.3.3.

6 - . NP-

384

6
10

1
5

2
10

15

10

10

6.3.3. - .
#include <stdio.h>
/* */
#define MAXN 200
/* */
const unsigned n = 6;
/* */
const char A[MAXN][MAXN] = {
{ 0, 10, 0, 5, 0, 0 },
{ 0, 0, 5, 0, 0, 15 },
{ 0, 0, 0, 10, 5, 0 },
{ 0, 10, 0, 0, 10, 0 },
{ 0, 5, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }};
unsigned vertex[MAXN], savePath[MAXN];
char used[MAXN];
int maxLen, tempLen, si, ti;
void addVertex(unsigned i)
{ unsigned j, k;
if (tempLen > maxLen) { /* - => */
maxLen = tempLen;
for (j = 0; j <= ti; j++) savePath[j] = vertex[j];
si = ti;
}
for (k = 0; k < n; k++) {
if (!used[k]) {
/* k */
/* , , */
if (A[i][k] > 0) {
tempLen += A[i][k];
used[k] = 1;
/* k */
vertex[ti++] = k; /* k */
addVertex(k);
used[k] = 0;
/* */
tempLen -= A[i][k]; ti--;
}
}
}
}
int main(void) {
unsigned i;
maxLen = 0; tempLen = 0; si = 0; ti = 1;
for (i = 0; i < n; i++) used[i] = 0;
for (i = 0; i < n; i++) {
used[i] = 1; vertex[0] = i;

6 - . NP-

385

addVertex(i);
used[i] = 0;
}
printf("- : \n");
for (i = 0; i < si; i++) printf("%u ", savePath[i] + 1);
printf("\n %d\n", maxLen);
return 0;
}

longpath.c
:
- :
3 4 5 2 6
40.

:
1. -
, , . ()
, ?
2. -
, ,
(, ).
3. ,
.

6.3.4.
, , :

6.3.4a. .
8
7
6
5
4
3
2
1

22

44

39

24

28

63

43

40

23

45

62

25

10

21

42

59

38

27

64

29

41

58

37

46

61

54

11

26

20

60

53

36

47

30

51

57

35

48

55

52

15

12

19

56

33

14

17

50

31

34

18

49

32

13

16

6.3.4. n = 8.
: n (n > 4) nn
. .

6 - . NP-

386

a , ,
. , 6.3.4.
n = 8 6.3.4.
( n2 )
. ,
. n
= 3 n = 4 ( 6.3.4):
K

6.3.4. n = 3 n = 4.
, ,
, . . . ,
" " " "
,
, di , di 8 (
5, 7 8 ).
, , , -
, , n2 8.n2 (
.
5.2.). o ,
:
/* board[][] nn */
void (x, y, i)
{ if (i == n*n) { /* */ }
board[x][y] = i;
for (___(u,v)_____(x,y))
if (0 == board[u][v]) /* */
(u, v, i+1);
board[x][y] = 0; /* */
}

, , . , ( startX startY) .
, , ..
, 6.3.4., .
diffX[] diffY[]

6 - . NP-

387

, (x,y) (x+diffX[i],
y+diffY[i]), i = 1,2, ..., maxDiff:
#include <stdio.h>
#include <stdlib.h>
/* */
#define MAXN 10
/* */
#define MAXD 10
/* */
const unsigned n = 6;
/* */
const unsigned startX = 1;
const unsigned startY = 1;
/* */
const unsigned maxDiff = 8;
const int diffX[MAXD] = { 1, 1, -1, -1, 2, -2, 2, -2 };
const int diffY[MAXD] = { 2, -2, 2, -2, 1, 1, -1, -1 };
unsigned board[MAXN][MAXN];
unsigned newX, newY;
void printBoard(void)
{ unsigned i, j;
for (i = n; i > 0; i--) {
for (j = 0; j < n; j++) printf("%3u", board[i-1][j]);
printf("\n");
}
exit(0); /* */
}
void nextMove(unsigned X, unsigned Y, unsigned i)
{ unsigned k;
board[X][Y] = i;
if (i == n * n) { printBoard(); return; }
for (k = 0; k < maxDiff; k++) {
newX = X + diffX[k]; newY = Y + diffY[k];
if ((newX >= 0 && newX < n && newY >= 0 && newY < n) &&
(0 == board[newX][newY]))
nextMove(newX, newY, i + 1);
}
board[X][Y] = 0;
}
int main(void) {
unsigned i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) board[i][j] = 0;
nextMove(startX-1, startY-1, 1);
printf(" . \n");
return 0;
}

knight.c

6 - . NP-

388

:
10
7
28
21
12
1

27 6 19 16
20 9 26 5
11 4 17 24
8 23 32 3
29 2 35 14
22 13 30 33

25
18
15
34
31
36

:
, ,
NP-, .. ( , ,
6.3.4.). ( 9 ) : ,
- .
, ,
.
:
:
1. , .
2. ,
. , ,
.
3. :
)
)
4. n (n > 4) nn .
. a
, .
5. n (n > 4) nn ,
. .
a ,
, .
6. n (n > 4) nn .

.
7.
(.. - k).
8. 7 5?

6.3.5.
.
. 1850 .
, .
.

6 - . NP-

389

6.3.5. n = 8.
: n nn (n 2)
, ( ,
).
n = 8 6.3.5. :
i = 1.
i , ""
(i+1)- ( ).
n (. . i = n) ,
, , ,
.
i- ,
(i1)-.
"" -.
C n2
n

, .
- , nn
, , .
, - ,
n!. n- , i , i- .
.

, . . ,
, .
:
void (i) { /* i- */
if (i > n) { ; }
for (_____k)
if (_____(i,k)) {
/* (i,k) */
_i-____(i,k);
(i+1);
_i-____(i,k);
}
}

, :
1) queens[N]: queens[i] ,
i- .

6 - . NP-

390

2) col[N]: col[i] 1, i , 0
.
3) RD[2*N-1] LD[2*N-1)] k-
(k = 1,2,...,2n1) . :
RD[i+k] , (i,k),
.
LD[N+i-k] , (i,k),
.
- .
, n.
#include <stdio.h>
#include <stdlib.h>
/* */
#define MAXN 100
/* */
const unsigned n = 13;
unsigned col[MAXN] , RD[2*MAXN - 1],
LD[2*MAXN], queens [MAXN];
/* */
void printBoard()
{ unsigned i , j ;
for (i = 0; i < n; i++) {
printf("\n");
for (j = 0; j < n; j++)
if (queens[i] == j) printf("x ");
else printf(". ");
}
printf("\n");
exit(0);
}
/*
void generate(unsigned i)
{ unsigned j;
if (i == n) printBoard();
for (j = 0; j < n; j++)
if (col[j] && RD[i + j] && LD[n + i
col[j] = 0; RD[i + j] = 0; LD[n +
generate(i + 1);
col[j] = 1; RD[i + j] = 1; LD[n +
}
}

*/

- j]) {
i - j] = 0; queens[i] = j;
i - j] = 1;

int main(void) {
unsigned i;
for (i = 0; i < n; i++) col[i] = 1;
for (i = 0; i < (2*n - 1); i++) RD[i] = 1;
for (i = 0; i < 2*n; i++) LD[i] = 1;
generate(0);
printf(" ! \n");
return 0;
}

queens.c

6 - . NP-

391

:
x
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
x
.
.
.
.
.
.
.
.
.

.
x
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
x
.
.
.
.

.
.
x
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
x
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
x

.
.
.
.
.
.
.
.
.
.
x
.
.

.
.
.
.
x
.
.
.
.
.
.
.
.

.
.
.
.
.
.
x
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
x
.

.
.
.
.
.
x
.
.
.
.
.
.
.

.
.
.
.
.
.
.
x
.
.
.
.
.

,
(n!) [-1998][, , -1980].
:
1. : . , , ,
.
2. ( )
?

6.3.6.
, . (
[Christofides-1975]),
- :
: c t (c, t ).
cl[i][j] ( , i = 1,2,...,c, j = 1,2,...t), j a

i. , :
1) - .
2) .
c1
t1

c2

t2

c3

t3

c4

6.3.6a. .

6 - . NP-

392

: 4 c1, c2, c3 c4 t1, t2 t3. , , :


t1 c1 5 , t1 c2 5 , t1 c3 5 ,
t2 c2 5 , t2 c3 5 ,
t3 c2 5 , t3 c3 5 , t3 c4 5 .

6.3.6.: : 5.
ticj(x) , ti x cj. ,
:
1.
1)
2)
3)
4)

t1c2(5), t3c3(5), t2 , c2 c3 .
t1c3(5), t3c2(5), t2 .
t2 c2(5), t1 c1(5), t3 c4(5)
t2 c3(5)

20 .
2.
1)
2)
3)

t1 c1(5), t2 c2(5), t3 c3(5)


t1 c2(5), t2 c3(5), t3 c4(5)
t1 c3(5), t3 c2(5), t2 .

15 . ,
.
6.3.6.
1.
1-5
t1
c2
t2

t3
c3

6-10
c3

c2

11-15
c1
c2
c4

2.
1-5
t1
c1
t2
c2
t3
c3

6-10
c2
c3
c4

11-15
c3

c2

16-20

c3

6.3.6. .

: ,
. ( 6.3.6.):
1

...

t1
t2
...

6.3.6. .
, . . i-
, j- , i- j- . -

6 - . NP-

393

,
:
- (. .
).
,
.
, 2 - ,
6.3.6.
t1
t2
t3

1
c1
c2
c3

2
c1
c2
c3

3
c1
c2
c3

4
c1
c2
c3

5
c1
c2
c3

6
c2
c3
c4

7
c2
c3
c4

8
c2
c3
c4

9
c2
c3
c4

10
c2
c3
c4

11
c3

c2

12
c3

c2

13
c3

c2

14
c3

c2

15
c3

c2

6.3.6. .
,
, . 5 5 (
6.3.6.):
5

10

15

20

...

t1
t2
...

6.3.6. .
, ,
:

mX = min(cl[i][j]), i = 1,2,...,c, j = 1,2,...,t, cl[i][j] 0.



mX : ti cj , i = 1,2,...,t,
mX cl[i][j].

, cl[i][j]
, , ,
- - , , .
generate(teacher, level, mX,
totalHours) 4 : teacher ,
, mX , totalHours
. ( level) mX , -, generate(0, level+1, mX, totalHours+mX).
, - , mX
. k teacher
( 1.3.3.). , cl[k][teacher]
mX, (teacher == N)
mX ..
, totalHours <
minimal ( - -
) , , . :
if (totalHours >= minimal) return;

6 - . NP-

394

. ., -
, .
#include <stdio.h>
/* */
#define MAXT 100
/* */
#define MAXC 100
/* */
const unsigned t = 3;
/* */
const unsigned c = 4;
unsigned cl[MAXC][MAXT] = {
{ 5, 5, 5 }, /* 1 */
{ 5, 5, 5 },
{ 5, 0, 0 },
{ 0, 0, 5 } /* C */
};
const unsigned MAX_VALUE = 20000;
char usedC[100][MAXC];
unsigned teach[MAXT], minimal;
void generate(unsigned teacher, unsigned level,
unsigned mX, unsigned totalHours)
{ unsigned i, j;
if (totalHours >= minimal) return;
if (teacher == t) {
unsigned min = MAX_VALUE;
for (i = 0; i < c; i++)
for (j = 0; j < t; j++)
if (cl[i][j] < min && 0 != cl[i][j]) min = cl[i][j];
if (min == MAX_VALUE) {
if (totalHours < minimal) minimal = totalHours;
}
else {
generate(0, level + 1, min, totalHours + min);
}
return;
}
/* teacher, min */
for (i = 0; i < c; i++) {
if (cl[i][teacher] > 0 && !usedC[level][i]) {
cl[i][teacher] -= mX;
usedC[level][i] = 1;
generate(teacher + 1, level, mX, totalHours);
usedC[level][i] = 0; /* */
cl[i][teacher] += mX;
}
}
/* ,

6 - . NP-

395

*/
if (i == c) generate(teacher + 1, level, mX, totalHours);
}
int main(void) {
unsigned i, j;
for (i = 0; i < 100; i++)
for (j = 0; j < c; j++) usedC[i][j] = 0;
minimal = MAX_VALUE;
generate(t, 0, 0, 0);
printf(" %u .\n",
minimal);
return 0;
}

program.c
:
15 .

:
1. , .
2. ?

6.3.7.
, ,
, , . (,
.) . ,
- ( ) ,
. , ,
, :
A 01 ( 0 , 1 ),
11, 0111. ,
0111, , AM.
, , :
, ("" ). , ,
, 0 1, a, b, c, d, :
1)
2)

"0", "1", "01", "10"


"a", "b", "c", "d"

, :
"0" "a"
"1" "b"
"01" "c"
"10" "d"
( )
. , .
, "0110" : "abba", "cd" .
.

6 - . NP-

396

, ,
. , , str1.
count, , ( count 0). , count, .
(, - "0110" "0"
"01"). () ,
. , , count
. count
, .
initLanguage().
N, transf[i].st1 i- (1 i n)
i- , transf[i].st2.
, int translation[] , , ,
.
0 9. .
#include <stdio.h>
#include <string.h>
#define MAXN
#define MAXTL

40 /* */
200 /* */

/* */
const unsigned n = 38;
/* */
char *str1 = "101001010";
struct
char
char
};
struct

transType {
*st1;
*st2;
transType transf[MAXN];

unsigned translation[MAXTL], pN, total = 0;


/* : 0 , 1- */
void initLanguage(void)
{ transf[0].st1 = ""; transf[0].st2 = "01";
transf[1].st1 = ""; transf[1].st2 = "1000";
transf[2].st1 = ""; transf[2].st2 = "011";
transf[3].st1 = ""; transf[3].st2 = "110";
transf[4].st1 = ""; transf[4].st2 = "100";
transf[5].st1 = ""; transf[5].st2 = "0";
transf[6].st1 = ""; transf[6].st2 = "0001";
transf[7].st1 = ""; transf[7].st2 = "1100";
transf[8].st1 = ""; transf[8].st2 = "00";
transf[9].st1 = ""; transf[9].st2 = "0111";
transf[10].st1 = ""; transf[10].st2 = "101";
transf[11].st1 = ""; transf[11].st2 = "0100";
transf[12].st1 = ""; transf[12].st2 = "11";
transf[13].st1 = ""; transf[13].st2 = "10";
transf[14].st1 = ""; transf[14].st2 = "111";
transf[15].st1 = ""; transf[15].st2 = "0110";
transf[16].st1 = ""; transf[16].st2 = "010";
transf[17].st1 = ""; transf[17].st2 = "000";
transf[18].st1 = ""; transf[18].st2 = "1";

6 - . NP-
transf[19].st1
transf[20].st1
transf[21].st1
transf[22].st1
transf[23].st1
transf[24].st1
transf[25].st1
transf[26].st1
transf[27].st1
transf[28].st1
transf[29].st1
transf[30].st1
transf[31].st1
transf[32].st1
transf[33].st1
transf[34].st1
transf[35].st1
transf[36].st1
transf[37].st1

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

"";
"";
"";
"";
"";
"";
"";
"";
"";
"1";
"2";
"3";
"4";
"5";
"6";
"7";
"8";
"9";
"0";

transf[19].st2
transf[20].st2
transf[21].st2
transf[22].st2
transf[23].st2
transf[24].st2
transf[25].st2
transf[26].st2
transf[27].st2
transf[28].st2
transf[29].st2
transf[30].st2
transf[31].st2
transf[32].st2
transf[33].st2
transf[34].st2
transf[35].st2
transf[36].st2
transf[37].st2

397
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

"001";
"0010";
"0000";
"1010";
"1110";
"1111";
"1101";
"0011";
"0101";
"01111";
"00111";
"00011";
"00001";
"00000";
"10000";
"11000";
"11100";
"11110";
"11111";

}
/* */
void printTranslation(void)
{ unsigned i;
total++;
for (i = 0; i < pN; i++)
printf("%s", transf[translation[i]].st1);
printf("\n");
}
/* */
void nextLetter(unsigned
count)
{ unsigned i, k;
if (count == strlen(str1)) { printTranslation(); return; }
for (k = 0; k < n; k++) {
unsigned len = strlen(transf[k].st2);
for (i = 0; i < len; i++)
if (str1[i + count] != transf[k].st2[i]) break;
if (i == len) {
translation[pN++] = k;
nextLetter(count + strlen(transf[k].st2));
pN--;
}
}
}
int main(void) {
printf(" : \n");
initLanguage();
pN = 0;
nextLetter(0);
printf(" : %u \n", total);
return 0;
}

translat.c

6 - . NP-

398

:
, . ?

6.4.
. , :
1)
2)

e ,
( ).
.

5 ( 5.4.4.) . :
1)
2)

( ) , . .

, : , (v1,v2, ... ,vk ), -
(v1,v2, ..., vk , vk+1), .

, ,
, "" :
- -, ,
, -
.
. NP- ,
.

6.4.1. ( )
1. () M . N , mi (1 i N). ,
, . . M.
2. ( ) ,
M . N , mi () ci.
, , . .
- M.
, , ((M.N)), ,
( 8). ,
, NP- .
.
, . .
2N ,
: M
.

6 - . NP-

399

. (
, ci mi c[i] m[i] .)
( ),
A = {a1,a2,...,ak }. S(a1,a2,...,ak ) S(a1,a2,...,ak ) =
m[a1]+m[a2]+...+m[ak ] . A
ak+1 , :
S(a1,a2,...,ak ) + m[ak+1] M, , A .
ak+1 , S(a1,a2,...,ak ) + m[ak+1] M, , a1,a2,...,ak (. . ).
c[A] = c[a1]+c[a2]+...+c[ak ] , - , :
void generate(i) {
if (____ > M) return;
if (i == N) {
/* , -
, */
return;
}
_i-_;
generate(i+1);
_i-_;
generate(i+1); /* . . i- */
}

. 2N- , ,
- M. .
, ,
, , ,
- . ,
, :
( -)
A = {a1,a2,...,ak }, B = {b1,b2,...,bp}. VT
, Vmax ,
. ,
VT c[b1] c[b2] ... c[bp] Vmax,
, . ,
, ,
, :
( ) + ( ) =
= (c[a1]+...+c[ak ]) + (VT (c[a1]+...+c[ak ]+c[b1]+...+c[bp])) =
= VT c[b1] c[b2] ... c[bp],
, - Vmax, , - - . generate():
float
float
float
float

Ttemp;
Vtemp;
VmaX;
totalV;

/*
/*
/*
/*

*/
*/
, */
*/

6 - . NP-

400

void generate(unsigned i)
{ if (Ttemp > K) return;
if (Vtemp + totalV < VmaX) return; /* */
if (i == N) {
if (Vtemp > VmaX) {
__;
VmaX = Vtemp;
}
return;
}
Vtemp += c[i]; Ttemp += m[i]; totalV -= c[i]; /* i */
generate(i+1);
Vtemp -=c [i]; Ttemp -= m[i]; /* _i-_; */
generate(i+1); /* . . i- "" */
totalV += c[i];
}
int main(void) {
totalV = c[1] + c[2] + ... + c[N];
generate(0);
return 0;
}

, i- . taken[] tN,
. - , , saveTaken[], sn . main() . N, M, c[N] m[N] .
#include <stdio.h>
#define MAXN 100
const unsigned n = 10;
const double M = 10.5;
const double c[MAXN] = {10.3,9.0,12.0,8.0,4.0,8.4,9.1,17.0,6.0,9.7};
const double m[MAXN] = {4.0,2.6,3.0,5.3,6.4,2.0,4.0,5.1,3.0,4.0};
unsigned taken[MAXN], saveTaken[MAXN], tn, sn;
double VmaX, Vtemp, Ttemp, totalV;
void generate(unsigned i)
{ unsigned k;
if (Ttemp > M) return;
if (Vtemp + totalV < VmaX) return;
if (i == n) {
if (Vtemp > VmaX) { /* */
VmaX = Vtemp; sn = tn;
for (k = 0; k < tn; k++) saveTaken[k] = taken[k];
}
return;
}
taken[tn++] = i; Vtemp += c[i]; totalV -= c[i]; Ttemp += m[i];
generate(i + 1);
tn--; Vtemp -= c[i]; Ttemp -= m[i];
generate(i + 1);
totalV += c[i];
}

6 - . NP-

401

int main(void) {
unsigned i;
tn = 0; VmaX = 0; totalV = 0;
for (i = 0; i < n; i++) totalV += c[i];
generate(0);
printf(" : %.2lf\n : \n", VmaX);
for (i = 0; i < sn; i++) printf("%u ", saveTaken[i] + 1);
printf("\n");
return 0;
}

bagrec.c
:
: 37.40
:
3 6 8

:
1. , 1.
2. , .

6.5.
, ,
6.5.2. 6.3.4.
. , .
G(V,E). (i,j)E ...
, i, j
. :

, (
, . :
o , .
o (
, ).
o (
/ / ).
o ( ""
).

, .

, , (. . ,
).
, (. . , ).
( , ).

6 - . NP-

402

, -
. ,
, .

6.5.1. "X"- "O"


, , -
( 10100 ). -,
:
33. 1 X, 2 O. ,
, .
(,
, X ).
6.5.1.:

X O

X
O

X O

X
X

6.5.1. X- O
6.5.1. T3 T4 ( 1 ), T2 ( 2, ), T1 .
, X- O,
( ).
checkPosition(int player, board), board , player. board1,board2,...,boardn
, board :
/* : 1 - player, */
/*
2 - */
/*
3 - */
int checkPosition(int player, board)
if ( ) {
if ( ) return 3; /* */
if (player == , ) return 1;
if (player != , ) return 2;

6 - . NP-

403

} else {
if (checkPosition(other_player,boardi)==1 i=1,..,n) return 2;
if (checkPosition(other_player,boardi)==2 i=1,..,n) return 1;
return 3;
}
}


, . 6.5., ,
( , )
, .

X
O X

T1

T2

X X
O X
O

X X
O X
O

T3

X X X
O X
O
O

O X X
O X
O

O X X
O X
O
X

T4

6.5.1. .
checkPosition() . ,
. , , ,
- ( 6.5.1.
). " 3
" .

6.5.1. 3 ( ).

6 - . NP-

404

checkPosition() X-
O. terminal(), ,
, , , :
#include <stdio.h>
/* */
const char startPlayer = 2;
/* */
char board[3][3] = {
{ '.', '.', '.' },
{ '.', 'X', '.' },
{ 'X', '.', 'O' }};
/* : 1, 1,
*
2, 2,
*
3,
*
0, .
*/
char terminal(char a[3][3])
{ unsigned i, j;
for (i = 0; i < 3; i++) {
/* */
for (j = 0; j < 3; j++)
if (a[i][j] != a[i][0]) break;
if (3 == j && a[i][0] != '.') {
if (a[i][0] == 'X') return 1; else return 2;
}
/* */
for (j = 0; j < 3; j++)
if (a[j][i] != a[0][i]) break;
if (3 == j && a[i][0] != '.') {
if (a[0][i] == 'X') return 1; else return 2;
}
/* */
if (a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[1][1] != '.')
if (a[0][0] == 'X') return 1; else return 2;
if (a[2][0] == a[1][1] && a[1][1] == a[0][2] && a[1][1] != '.')
if (a[2][0] == 'X') return 1; else return 2;
}
/* ( ) */
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
if (a[i][j] == '.') return 0;
return 3;
}
/* : 1, player,
*
2,
*
3, */
char checkPosition(char player, char board[3][3])
{ unsigned i, j, result;
int t = terminal(board);
if (t) {
if (player == t) return 1;
if (3 == t) return 3;
if (player != t) return 2;
}

6 - . NP-

405

else {
char otherPlayer, playerSign;
if (player == 1) { playerSign = 'X'; otherPlayer = 2; }
else { playerSign = 'O'; otherPlayer = 1; }
/* char board[3][3];
*
*/
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (board[i][j] == '.') {
board[i][j] = playerSign;
result = checkPosition(otherPlayer, board);
board[i][j] = '.';
if (result == 2) return 1; /* . , */
/* player */
if (result == 3) return 3; /* */
}
}
}
/*
* player */
return 2;
}
}
int main(void) {
printf("%u\n", checkPosition(startPlayer, board));
return 0;
}

tictac.c
""
, , .
:
1. , X- O ,
: , , . . , . , .
2. X- O ,
nn, , , m .
- m 5.
3. , 33, , .
4. :
) ,
) ( ))
) (.. )

6.5.2.
X- O. , ( 6.5.1.), ,
. , 1.

6 - . NP-

406

( ): +,
1, , 2, 0, .
: i
i1,i2,..,ik V[i]
:

max( V [i1 ],V [i2 ],...,V [ik ]), 1


V [i]
min(V [i1 ],V [i2 ],...,V [ik ]), 2
, , ,
1, (
, /
). ( ),
.
value minimax( i) {
if (i__) return __;
(i1, i2, .., in) i;
if (i_e___)
return min(minimax(i1), .., minimax(in));
if (i_e___)
return max(minimax(i1), .., minimax(in));
}

, - - . X- O -
, + 0.
. , ,
,
(. . 6.5.4.). minimax() , .
.
:
X- O ,
.

6.5.3. -
- , . .
6.5.3. ,
A1. A1 V[B1],
V[B2], V[B3] .. V[B1]
. , B1 , V[B1] = max(V[C1,C2,C3]) = max(5,4,3) = 5. A1
, V[B1] = 5 , A1 - 5.
- B2. V[B2]
D1,D2,D3,... . -
, ,
D1, V[D1] = 6. , B2
6 ( ). , V[A1] 5.
B2 ( , -)

6 - . NP-

407

D2, D3,... , , V[B2] 6,


V[A1] 5.
, .
6.5.3.: , V[C1] = 4, V[C2] = 5, V[C3] = 6.
V[B1] = min(V[C1], V[C2], V[C3]) = min(4, 5, 6) = 4. , V[A1] 4. -
, V[D1] = 3, , V[B2] 3. V[A1] 4 V[B2] 3 , - B2 (-).
1

C1

min

max

B1

C2

C3

V[A1] = min(V[B1],V[B2],...);

max

B2

D1

V[B1] = max(V[C1],V[C2],...),...

D2

D3

6.5.3. .
: ,
, -
- :
-
- : , , . -, ,

, . -
- .
-
- .
- +. -, - ,
. - -
.
, :
- - .
, , , , - .
- ( ) -
- .
- ( ) -
- .

6 - . NP-

min

B1

C1

C2

max

V[A1] = max(V[B1],V[B2],...);

V[B1] = min(V[C1],V[C2],...), ...

min

B2

C3

408

D1

D2

D3

6.5.3. .
, .
minimaxCutoff() , + (
):
value
Na
Nb
if
if

minimaxCutoff(N, A, B) {
= A; /* Na - ,
= B; /* Nb - ,
(N__) return __;
(N____)
for (__Ni__N) {
val = minimaxCutoff(Ni, Na, Nb);
Nb = min(Nb, val);
if (Nb <= Na) break; /* -
}
return Nb;
} else { /* if (N____) */
for (__Ni__N) {
val = minimaxCutoff(Ni, Na, Nb);
Na = max(Na, val);
if (Na >= Nb) break; /* -
}
return Na;
}

*/
*/

*/

*/

- - ,
.
:
X- O ,
- .
- .

6.5.4. -
. - , ,
- . .
, , . , , ,

6 - . NP-

409

.. , ,
, .
, [Brassard,Bratley1996]:
10; 5; , 3,25; 1;
( )
.
, , , +,
. 0.
6.5.2. ,

:
value eval( i) {
return ______;
}
value minimax( i, depth) {
if (i__) return __(+,-,0);
if (depth > maxDepth) return eval(i); /* */
_(i1, i2, .., in)____i;
if (i_e___)
return min(minimax(i1,depth+1), .., minimax(in,depth+1));
if (i_e___)
return max(minimax(i1,depth+1), .., minimax(in,depth+1));
}

- maxDepth , -
. , . , ,
maxDepth ( eval(i)) - : ( maxDepth + 1), ,
- .
- - .
1997 Deep Blue, , 200,000,000 . -
, , .
eval() (
). ,
,
.
:
1. X- O.
2. X- O -
.

6.6.
6.6.1.
6.1.
( 6.1.).

6 - . NP-

410

6.2.
, , ( 6.1.).
6.3.
( 6.1.) :
n .
n, -
q (q > 1, q < n).
6.4.
6.2. , NP- A
B, B NP-. ( 6.2.)
6.5.
, NP ( 6.2.) (, NP- ).
6.6.
" n, -
q (q > 1, q < n)." NP.
NP-?
6.7.
6.3. (,
)?
6.8.
. (
6.3.1.)
6.9.
( X 2 X3 X1) X2 ( X 1 X 3 )?
6.10.
A (B C) = (A B) (A C),
. ( 6.3.1.)
6.11.
. ( 6.3.1.)
6.12.
A B A B .

6 - . NP-

411

6.13.
. ,
.
6.14. , , {,
} {, } {, , }.
6.15. , {, } {, , }?
6.16.
,
, .. r (1 r n)
r . ( 6.3.2.)
6.17.
6.3.2.
6.18.
.
( 6.3.2.)
6.19.
- , , . () , ? ( 6.3.3.)
6.20.
- , ,
(, ). ( 6.3.3.)
6.21.
6.3.3. ,
.
6.22.
6.3.4. , .
6.23.
6.3.4. ,
. , ,
.
6.24.
( 6.3.4.):
)
)
6.25.
n (n > 4) nn .
. a , . (
6.3.4.)

6 - . NP-

412

6.26.
n (n > 4) nn , . .
a , ,
. ( 6.3.4.)
6.27.
n (n > 4) nn .

. ( 6.3.4.)
6.28.

(.. -
k).
6.29.
6.28. 6.26?
6.30.

6.3.5.:
. , , ,
.
6.31.
( )
? ( 6.3.5.)
6.32.
6.3.6. , .
6.33.
6.3.6. ?
6.34.
6.3.7. , .
?
6.35.
, 1 6.4.1.
6.36.
6.4.1. ,
.
6.37.
, X- O ,
: , , . . , . , . ( 6.5.1.)

6 - . NP-

413

6.38.
X- O ,
nn, , , m . m 5. ( 6.5.1.)
6.39.
, 33, ,
. ( 6.5.1.)
6.40.
:
) ,
) ( ))
) (.. )
( 6.5.1.)
6.41.
X- O ,
.
( 6.5.2.)
6.42.
X- O ,
- .
- . ( 6.5.3.)
6.43.
X- O.
( 6.5.4.)
6.44.
X- O -
. ( 6.5.1.)

6.6.2.
- NP-
- NP- , . NP-
. ,
NP-, ,
:

( 9).
, ,
.
( 9). NP- . , , , .
, NP-,
.

6 - . NP-

414


( 8).
. .
, ,

. .

, , 1979
"" NP- [Garey,Johnson-1979]. ,
, ( ). - - :

( , ). ,
- .
. : (
, , .) .
, , ,
.
. ( ) , ( - )
, , .
, . ,
[Garey,Johnson-1979],
.
:

6.45. 3- (3-COL)
.
"" ( )
: , , , , ,
.
, .
, , 3 .
,

..
- .
- , - ,
.
- - .
6.46.
.
, .
: 5.4.4., 6.2., 9.2.3. .
6.47.
n k, 1 k n.
, k .
. ,
(
k = n).

6 - . NP-

415

6.48.
m C1, C2, ..., Cm X1, X2, ..., Xn
.
"" "" X1, X2, ..., Xn, C1, C2, ..., Cm .
6.3.1.
6.49. -
n k, 1 k n.
s, t .
s t, k .
6.3.3.
6.50.
n k, k 1.
, ,
( ) - k.

, .
6.51.
A aA
s(a). k.
BA , s(x)
xB k.
1 6.4.1. . 8.2.1., .
6.52.
A. a s(a).
A A1 A2,
s( x ) s( y ) .
xA1

yA2

,
( ) ( ) ,

. 8.2.2.
6.53. .
A aA
s(a). k.
BA , s(x), xB k.
.
6.54.
A n . aA s(a). b k, 1 k n.
k A1, A2, ..., Ak , Ai
(1ik) b.
k ,
b , . -

6 - . NP-

416

k,
.
6.55.
n ( 1,2,...,n)
. (a, b, c, d) , a, b, c d.
k, 1 k n.
kk,
, .
[-5/1998]
6.56.
n S = {s1,s2,...,sn} W = {w1,w2,...,w2n} 2n
, wi n S.
2n nn, .
. C nn, S ,
W.
6.57.
G(V,E) n k, 1 k n.
UV, k ,
i,jU , (i,j)E.
5.7.2.
6.58.
G(V,E).
E E1 E2
, (i,j), (j,k), (k,i) (. .
G1(V,E1), G2(V,E2) 3).
6.59.
G(V,E) n k, 1 k n.
G U, UV - k ,
iV, iU jU , (i,j) E.
6.60.
G(V,E) m k, 1 k m.
1
k ( 1 k) , ,
.
, , k
. NP-
. [Gibbons,Rytter1987].
6.61. -
S = {s1,s2,...,sn} ( 0 1)
k.
s - k , pS
s.
, , - NP-.

6 - . NP-

417

6.62.
G(V,E) m , E1, E1E k, 1 k m.
( ),
eE1 , - k.
6.63. ""
A = <a1,a2,...,an> B = <b1,b2,...,bm>
.
Div(x,Y) (Y ) yY, x
y. c, Div(c, A) > Div(c,
B).
NP-
. c , 1.
, NP-. ,
( ) - .
6.64.
a, b, c.
x y , (a.x2) + (b.y) = c
, 19
x y ,
a, b c.
6.65.
a, b c.
x, x c , x2 a (mod b).
6.66.
n {(a1,b1), (a2,b2), ..., (an,bn)},
ai bi, 1 i n.
x , ai x (mod bi), 1 i n.
6.67.
k M nn, 0 1.
M - k , . . (ai, bi, ci, di), 1 i k, ai bi, ci di
, :
- (i,j), 1 i, j n M[i][j] == 1 ,
l (1 l k) al i bl cl j dl.
- : l (1 l k), i (al i bl),
j (cl j dl) M[i][j] == 1.
, ( ):
- - k
.
6.68.
, s t r
C = {(a1,b1), (a2,b2), ..., (ar,br)}.
s t , (ai,bi)C -
ai, bi .

6 - . NP-

418

6.69.
G(V,E) n m k, 1 k m.
E1 E k ,
G(V,E1) .
: n
s1,s2,...,sn, . ,
() ()
.
6.70.
G(V,E) 2n m k, 1 k m.
G U W,
n- , (i,j) E, iU, jW - k.
,

.
6.71.
A n C (a, b, c) .
X Y n . , X Y f:XY, X
Y : Y X.
, f:X{1,2,...,n} X 1 n.
f:X{1,2,...,n},
(a,b,c)C :
f(a) < f(b) < f(c)
f(b) < f(c) < f(a)
f(c) < f(a) < f(b)
6.72.
n- A C (a, b, c),
a, b, c A.
f:A{1,2,...,n} , (a, b,
c)C f(a) < f(b) < f(c) f(c) < f(b) < f(a).
6.73.
S k , n r.
H(x,y) x y , x y. x
n , y, yS H(x,y) r.
NP- [Frances-Litman-1997].
6.74. B-
G(V,E) n k, 1 k n.
G, . .
f:V {1,2,...,n} , (i,j) E |f(i)f(j)| k.
6.75.
G(V,E).
E1, E1E ,
G1(V,E1) 3, 0.

6 - . NP-

419

6.76.
G(V,E) n k, 1 k n.
UV - k ,
(i,j)E i,j U.
6.77.
G(V,E) n k, 1 k n.
f:V {1,2,...,n},
| f (i) f ( j) | k
( i , j )E

6.78.
G(V,E) n k-
{(s1,t1), (s2,t2),..., (sk ,tk ) }.
k ( ) s i
ti.
6.79.
G(V,E) n k, 1 k n.
V t, 1 t k V1, V2, ..., Vt , Vi Gi(Vi,Ei)G .
6.80. -
G1(V1,E1), G2(V2,E2) k.
F1E1 F2E2 , :
- F1 F2 -
k.
- G1(V1,F1), G2(V2,F2) .
6.81. 2-
C1,C2,...,Cm n X = {X1, X2, ...,
Xn}, Xi, XjX.
k, 1 k m.
"" "" , k .
k = m - 6.4. 2-SAT
( m) .
6.82. (k-)
G(V,E) n k, 1 k n.
UV k ,
U G(U,E) , . . iU, jU (i,j) E.
6.83.
G(V,E) 2n .
:
- (2n2n)/2 +1 .
- (2n2n)/2 +1 n-.
6.84.
G(V,E).
, .. U, UV, :
- i,j U , . (i,j) E
- i V\U, j U , (i,j) E.

6 - . NP-

420

6.85.
X, Y, Z n M
m (xi, yi, zi), xiX, yiY, ziZ, 1 i m.
Q M n ,
(i, j, k)Q, (u, v, w)Q i u, j v, k w.
-
( 5.7.6.), .
6.86.
S m C1,C2,...,Cm.
S S1 S2 , Ci , i =
1,2,...,m S1, S2.
6.87.
C1,C2,...,Cm k, 1 k m.
k , .
6.88.
A n aA s(a).
j k, 1 k n.
A k A1,A2,...,Ak , i =
1,2,,k:
s ( x) 2 j
xAi

6.89. 3-
A 3m b. aA s(a), b/4 < s(a) < b/2. ,
s(a) mb .

aA

A m A1, A2, ..., Am ,


Ai 3 A Ai ( i
= 1,2,...,m) b.
6.90. " "
, G(V,E) t . U V, ,
. k.
" " - k ,
" " , . . ,
TU , :
- T - k .
- iV jT, i j t.
6.91. " "
G(V,E) n V0V.
"" "" V0
V - 4 , . . V0, E1, V1, E2,
V2, E3, V3, E4, V4 , :
- Vi V, 0 i 4.
- Ei E, 1 i 4.
- V4V.

6 - . NP-

421

- (u,v) Ei vVi-1, 1 i 4.
- Ei, , 1 i 4.
- Vi = Vi-1 {w: (v,w) Ei}, 1 i 4.
6.92. -
G(V,E) n . (i,j)E
e(i,j) l(i,j), . s t k w.
s t, :
- - w.
- - k.
,
- ( 5.4.2.), .
6.93. -
G(V,E) m k, 1 k m.
E1E - k ,
, . . E1
eE, eE1 E1.
6.94.
G(V,E) 3n .
V n V1, V2,...,Vn
(, V), 3 , - ,
Vi = {ui,vi,wi} (ui, vi), (vi, wi), (wi, ui) E, 1 i n.
6.95.
G(V,E) n k, 1 k n.
V t, 1 t k V1, V2,...,Vt (, V), ,
Vi Gi(Vi,Ei) G .
6.96.
G(V,E) n k, 1 k n.
V t, 1 t k
V1, V2,...,Vt (, V) ,
Vi Gi(Vi,Ei)G , . .
.
6.97.
G(V,E) n k, 1 k n.
t, t k V1, V2,...,Vt, V (
), :
- Vi Gi(Vi,Ei) G .
- (u,v)E Vi, u
v.
6.98.
G(V,E) n m k, 1 k m.
d, d n.
E1E k ,
G(V,E1)G , - d.

6 - . NP-

422

6.99.
G(V,E) m k, 1 k m.
E1E k ,
G(V,E1) G - i, jV.
6.100. k-
G(V,E) n m . k
b, 1 k n 1 b m.
E1E - b ,
G1(V,E1) G k-.
6.101.
G(V,E) n k.
f:V{1,2,...,n} , i, 1 i n
(u,v)E, f(u) i f(v), - k.
6.102.
G(V,E) m , s, t
k, 1 k m.
E1E - k ,
P Q s t ( )
eE1, P Q.
6.103.
G(V,E) n k, 1 k n.
U, UV p (p k) ,
G1(U,E1) G, U, p .
6.104.
G(V,E) n k, k n.
t, t k V1, V2,...,Vt V (
) , ( 1 i t):
- Gi(Vi,Ei)G, Vi, .
- Vi - 4.
6.105.
G1(V1,E1) G2(V2,E2) k.
U V1V2 (. .
i,j , iV1, jV2) k , <u,v>U
<x,y>U, (u,x) E1 , (v,y) E2.
6.106.
W, X, Y, m .
uWXY f(u). b.
3m- WXY m A1,A2,...,Am , :
- Ai W, X
Y.
f (u ) b , Ai, 1 i n.

uAi

6 - . NP-

423

6.107.
X. (x,y), x,yX
d(x,y). b.
X X1, X2, X3
, Xi (1 i 3) x,yXi d(x,y) b.
6.108. 2-
G(V,E) s.
E1E - s ,
(v,w)E , : 1) (v,w) E1; 2) (v,x) E1 (x,w) E1 xV.
, G1(V,E1) 2-
G(V,E).
2- ( - t-) t- ,
.
6.109.
G(V,E) k, 1 k n.
G , k , .. .
[Dunne-1987]
6.110.
G(V,E) k, 1 k n.
G , , k.
6.111.
.
b.
, :
- 5 .
- - b.
6.112.
G(V,E) n k, 1 k n.
, G1(V,E1) :
- G1(V,E1) .
- G(V,E1) - k.
6.113. "-"
G(V,E) n , s
. "-" "-". k.
G1(V1,E1) G, :
- s V1
- wV1 w "-", , w, E1.
- wV1 w "-", , w, E1.
- E1 - k .
6.114.
G(V,E) b.

6 - . NP-

424

,
u v, u,vV, - b.
6.115.
T . tT l(t) 1 2.
T . d (deadline).
, T d : T{1,2,...,n}, :
- u 0 t T, (t) u (t) + l(t) - 2.
- tT, (t) + l(t) d.
, i -
j (j) (i) + l(i).
6.116. - 2
T . tT l(t). d.
, d.
6.117.
G(V,E) n ,
- 2 (. . - ).
k.
(v1,v2,...,vn) (V0,V1,...,Vn)
V, :
- Vi - k V (1 i n1).
- V0 , Vn ( 0).
- i = 1,2,...,n : viVi; Vi\{vi}
Vi-1; Vi-1 u, (vi,u)E.
. -
, .
( 16 32),
.
" " ( . straight-line
programs), . " " , " ",
k .
6.118.
f n X1, X2,...,Xn,
A = <a1, a2,...,an>, f(a1, a2,...,an) = 1. k.
f ,
- k.
, :
- , , X1, X2,...,Xn.
- 0 1.
- , , 0.
- , , 1.
(X1, X2,...,Xn)
, ,
. -

6 - . NP-

425

. f(X1, X2,...,Xn),
A ,
f(A). t - v
v , t.

-
6.119.
mn
. 5
1 ( ) 6.6.2.

6.6.2. .
,
60 (.. m.n = 60) ,
.
6.120. n-
n- , n- 1.
n. n- ,
.
6.121.
n nn, 1 n2 , ,
, (n/2).(n2+1).
nn.
6.122.
n ( 1.30.).
, /
, 1 (1.5.3.).

7

Fools ignore complexity.
Pragmatists suffer it.
Some can avoid it.
Geniuses remove it.
~ Epigrams in Programming
-, -
, . ,

.

.
? .
, -
(). . ,
, ().
,
. , , -. , ,
. .
, , ,
, - .

7.1. k-
, , . ,
n1 :
int findMax(int m[], unsigned n) /* */
{ unsigned i;
int max;
for (max = m[0], i = 1; i < n; i++)
if (m[i] > max) /**/
max = m[i];
return max;
}

maximum.c
? ,
.
, . ,
, (-

7 -

428

), , . ,
n1.
.
, . , .
, (log2 n).

. ,
,
. ,
, . ,
x y .
.
. , , /
2n1 (
, /**/.). ,
,
.
- , - 3n/2 . :
, - , - , .
void findMinMax(int *min, int *max, const int m[],const unsigned n)
/* */
{ unsigned i, n2;
for (*min = *max = m[n2 = n/2], i = 0; i < n2; i++)
if (m[i] > m[n-i-1]) {
if (m[i] > *max)
*max = m[i];
if (m[n-i-1] < *min)
*min = m[n-i-1];
}
else {
if (m[n-i-1] > *max)
*max = m[n-i-1];
if (m[i] < *min)
*min = m[i];
}
}

maximum.c
, ?
, , , - . : - , - , - -:
/* */
void swap(int *el1, int *el2)
{ int tmp = *el1; *el1 = *el2; *el2 = tmp; }
int findSecondMax(int m[], unsigned n)
{ int x,y;

7 -

429

unsigned i;
x = m[0]; y = m[1];
if (y > x)
swap(&x,&y);
for (i = 2; i < n; i++)
if (m[i] > y)
if ((y = m[i]) > x)
swap(&x,&y);
return y;
}

maximum.c
. , , (n2)-
. ,
2n3.
- k- -
n- . (nk+1)- . , , ,
< ( ) > ( ), k- .
,
k- k- . , ,
k, n.log2 n. ,
(n + k.log2 n), k
( (n),
(n.log2 n) , - , 3.1.9.).
, (min(n + k.log2 n, n+(nk+1).log2 n)). ,
k > [n/2], . , k
n/2, ,
k (nk+1) ,
.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int m[MAX];
const unsigned n = 100; /* */
const unsigned k = 10; /* */
void init(int m[], unsigned n) /* */
{ unsigned i;
for (i = 0; i < n; i++)
m[i] = rand() % (2*n + 1);
}
void siftMin(int
{ int i,j;
int x;
i = l; j = i +
while (j <= r)
if (j < r)
if (m[j] >
j++;

l,int r) /* . */

i + 1; x = m[i];
{
m[j+1])

7 -
if (x <= m[j])
break;
m[i] = m[j];
i = j;
j = j*2 + 1;
}
m[i] = x;
}
void siftMax(int l,int r) /* . */
{ int i,j;
int x;
i = l; j = i + i + 1; x = m[i];
while (j <= r) {
if (j < r)
if (m[j] < m[j+1])
j++;
if (x >= m[j])
break;
m[i] = m[j];
i = j;
j = j*2 + 1;
}
m[i] = x;
}
void heapFindK(unsigned k) /* k- */
{ int l,r;
char useMax;
if (useMax = (k > n/2))
k = n k - 1;
l = n/2; r = n - 1;
/* */
while (l-- > 0)
if (useMax) siftMax(l,r); else siftMin(l,r);
/* (k-1)- */
for (r = (int)n-1; r >= (int)(n-k); r--) {
m[0] = m[r];
if (useMax) siftMax(0,r); else siftMin(0,r);
}
}
void print(int m[], unsigned n) /* */
{ unsigned i;
for (i = 0; i < n; i++)
printf("%8d", m[i]);
}
int main(void) {
init(m,n);
printf(" :"); print(m,n);
printf("\n k- : k=%u", k);
heapFindK(k);
printf("\nk- : %d", m[0]);
return 0;
}

heap.c

430

7 -

431

-
. , (
3.2.2.), cj j
. , [l,r].
cl, cl+1, cl+2, ... j,
- k. j. ,
,
.
, ( 3.1.6.)
, .
,
( ).
l = 0, r = n1 x = m[k] (,
0 n1).
i j :
m[h] x, h < i
m[h] x, h > j
i>j
:
i < k. x - .
, l = i. ( 7.1.)

j i

7.1. i < k.

j > k. x - .
, r = j. ( 7.1.)

j i

7.1. j > k.

j < k < i. x . , -
, - . . ( 7.1.)

j ki

7.1. j < k < i.


,
i, j k. 3 k- k- .
void find(int m[],unsigned n,unsigned k) /* k- */
{ int i,j,l,r;
int x;
l = 0; r = n - 1;
while (l < r) {
x = m[k]; i = l; j = r;
for(;;) {

7 -

432

while (x > m[i]) i++;


while (x < m[j]) j--;
if (i > j)
break;
swap(m + i, m + j);
i++;
j--;
}
if (j < (int)k)
l = i;
if ((int)k < i)
r = j;
}
}

mid_elem.c
2n,
, k- , . -, ,
(min(n + k.log2 n, n + (nk+1).log2 n)), , - . , - ,
1, (n2). ,
, ,
- .
, ,
. x,
( - m[r]),
mid, , p, l
. k p, k- (l,mid).
(kp)- (mid+1,r).
, ( ):
unsigned partition(unsigned l,unsigned r) /* */
{ int i;
unsigned j;
int x;
i = l - 1; x = m[r];
for (j = l; j <= r; j++)
if (m[j] <= x) {
i++;
swap(m+i,m+j);
}
if (i == (int)r) /* <= x. 1. */
i--;
return i;
}
unsigned find(int l, int r, unsigned k) /* */
{ unsigned mid, p;
if (l == r)
return l;
mid = partition(l,r);
p = mid - l + 1;
return k < p ? find(l,mid,k) : find(mid+1,r,k-p);
}

mid_el2.c

7 -

433

,
, -.
, x. x ,
, . .
.
x? , , , ,
. . , k- 28n . n 55
. , ( 3.1.4.), n(n1)/2
, n 55 28n n(n1)/2.
, 28t t < n. n/7
, 7 ,
(), . , 7(71)/2 = 21 .
, 21(n/7) = 3n.
n/7-
(). 28(n/7) = 4n .
:
1. 7. Si, i = 1, 2, ..., n/7.
- 7 .
2. Si mi.
3. M mi, .
- . , partition(), x L[] :
L1[], - x, L2[], x, L3[],
- x.
unsigned select(int L[],
/* */
unsigned k) /* */
{ n = length(L); /* L[] */
if (n <= 7) {
bubbleSort(L,n);
return L[k];
}
/* L n/7 S[i] 7 . */
split(L, S = {S[i] | i = 1,2,...,n/7});
for (i = 0; i < n/7; i++)
x[i] = select(S[i],3); /* */
M = select({x[i]| i=1,2,...,n/7}, n/14);
partition(L,L1,L2,L3);
if (k <= length(L1)) then
return select(L1,k);
else if (k > length(L1) + length(L2)) then
return select(L3,k-length(L1)-length(L2));
else
return M;
}

7 -

434

7.1. .
x , 2n/7 - x, 2n/7 - x ( 7.1.).
3n , 4n ,
n , 28(5n/7)
(
2n/7 ). ,
28n . . . . , 28
, 2, . , n
16384
. , n > 16384 ,
- . 28n ,
15n. , , , 391/72
5,4306.n. , 3n,
2,95.n ! [Dor,Zwick-1996]
:
1. k- , .
2. , k- ,
, ,
i, j k, 7.1., 7.1. 7.1.
3. k- , , .
4. 5 ? 3?
? .
5. .

7.2.
7.1. n- (. . ,
). , , n/2 .
{2, 3, 3, 1, 3} 3, {1, 1, 2, 3}
.
, , . - , . ,

7 -

435

, (
) , - . -
CDataType, char.
char , , int
float.
, ,
n/2 . findMajority(),
, , , ,
( ). 1, , 0
.
count(), - . - .
#include <stdio.h>
#define CDataType char
unsigned count(CDataType m[], unsigned size, CDataType candidate)
{ unsigned cnt, i;
for (i = cnt = 0; i < size; i++)
if (m[i] == candidate)
cnt++;
return cnt;
}
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, size2 = size / 2;
for (i = 0; i < size; i++)
if (count(m, size, m[i]) > size2) {
*majority = m[i];
return 1;
}
return 0;
}
int main(void) {
CDataType majority;
if (findMajority("AAACCBBCCCBCC", 13, &majority))
printf(": %c\n", majority);
else
printf(" .\n");
return 0;
}

major1.c
(n2), n-
, .
, . , count()
, . ,
, . ,
. ,
, .
(n/2)- . ,

7 -

436

, , ,
.
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, j, cnt, size2 = size / 2;
for (i = 0; i <= size / 2; i++) {
for (cnt = 0, j = i; j < size; j++)
if (m[i] == m[j]) cnt++;
if (cnt > size2) {
*majority = m[i];
return 1;
}
}
return 0;
}

major2.c
, , , - , n/2+1 , (n2). . , ,
, ,
.
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, j, cnt, size2 = size / 2;
for (i = 0; i <= size / 2; i++) {
for (cnt = 0, j = i; j < size; j++)
if (cnt + size - j <= size2)
break;
else if (m[i] == m[j])
cnt++;
if (cnt > size2) {
*majority = m[i];
return 1;
}
}
return 0;
}

major3.c
,
: , . . . - - .
(n2).
, - . , , , , . .
(, ,
, , .):
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ heapSort(m, size); /* mergeSort(m,size); */
if (count(m, size, m[size / 2]) > size2) {
*majority = m[size / 2];

7 -

437

return 1;
}
return 0;
}

major4.c
,
.
( 3.1.9.) ( 7.4. -),
(n.log2 n) - ,
(n.log2 n). , .
(n.log2 n) 2 3 , -
(n2).
( k- ) , . , , , ,
(n), 5,43n163 , n
> 32. ( 7.1.)
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ CDataType med;
med = findMedian(m, size);
if (count(m, size, med) > size2) {
*majority = med;
return 1;
}
return 0;
}

major5.c
, ,
, . ,
,
.
.
( 3.2.2.).
.

n/2 . (k), ,
k, .
(n+k). k ( k < n)
(n).
#define MAX_NUM 127
CDataType cnt[MAX_NUM + 1];
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, j, size2 = size / 2;
/* */
for (i = 0; i < MAX_NUM; i++)
cnt[i] = 0;
/* */
for (j = 0; j < size; j++)
cnt[m[j]]++;
/* */
for (i = 0; i < MAX_NUM; i++)

7 -

438

if (cnt[i] > size2) {


*majority = i;
return 1;
}
return 0;
}

major6.c
, , , .
( , ). ,
x , .
.
. :
1)
2)
3)

. .
x, . x .
x y, .
x, y. ( x , y .)

, ,
. - (
) , .
,
, 0,
size1.
unsigned count(CDataType m[], unsigned left,
unsigned right, CDataType candidate)
{ unsigned cnt;
for (cnt = 0; left <= right; left++)
if (m[left] == candidate)
cnt++;
return cnt;
}
char findMajority(CDataType m[], unsigned left,
unsigned right, CDataType *majority)
{ unsigned mid;
if (left == right) {
*majority = m[left];
return 1;
}
mid = (left + right) / 2;
if (findMajority(m, left, mid, majority))
if (count(m, left, right, *majority) > (right - left + 1) / 2)
return 1;
if (findMajority(m, mid + 1, right, majority))
if (count(m, left, right, *majority) > (right - left + 1) / 2)
return 1;
return 0;
}

major7.c

7 -

439

? , - . .
( ) 0, n 2n , 1), 2) 3).
. n- T(n), :
T(1) = 0
T(n) = T(n/2) + 2n
( 1.4.10) , T(n) (n.log2 n).
- ? ,
, , ,
:
1. ,
.
2. , ,
, .
. ,

. , {1,1,2,3,4} ( ) 3
4 ( ), {1,1,2}, 1 .
, : 1)
, 2) ,
( ) . ,
. , : 1 2
. ,
: , .
( ). , , . ,
- n/2 . ,
: (,
, ).
,
.
, . (: AA BB A). ,
, (: AA B).
, - , .
, .
n- T(n), -
:
T(1) = 0
T(n) = T(n/2) + n/2
( 1.4.10.) , T(n) (n).
,

. , ,
. , ,
.

7 -

440

void findMajority(CDataType m[],unsigned size,CDataType *majority)


{ unsigned i, curCnt;
char part = 0;
do {
for (curCnt = 0, i = 1; i < size; i += 2)
if (m[i - 1] == m[i])
m[curCnt++] = m[i];
if (i == size) {
m[curCnt++] = m[i - 1];
part = 1;
}
else if (part)
m[curCnt] = m[size - 2];
else if (m[size - 2] == m[size - 1])
m[curCnt] = m[size - 2];
else
curCnt--;
size = curCnt;
} while (size > 1);
*majority = m[0];
}

major8.c

.
, , .
,
. ? , ,
,
(,
). -
, , ,
, ,
. ,
. , . . .
void findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, curCnt;
do {
for (curCnt = 0, i = 1; i < size; i += 2)
if (m[i - 1] == m[i])
m[curCnt++] = m[i];
if (size & 1)
*majority = m[size - 1];
size = curCnt;
} while (size > 0);
}

major9.c
? . ,
, ,
. , (. . , ),
. :

7 -

441

,
. , , ,
: .
:
.
void findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, curCnt;
do {
for (curCnt = 0, i = 1; i < size; i += 2)
if (m[i - 1] == m[i])
m[curCnt++] = m[i];
if (!(curCnt & 1))
m[curCnt++] = m[size - 1];
size = curCnt;
} while (size > 1);
*majority = m[0];
}

major10.c
( -)
,
. 1.
m[i-1] m[i], cnt[i-1] cnt[i],
:

1. m[i-1] == m[i]
, cnt[i-1] + cnt[i].

2. m[i-1] != m[i]
2.1. cnt[i-1] == cnt[i]
.
2.2. cnt[i-1] < cnt[i]
m[i] cnt[i] - cnt[i-1].
2.3. cnt[i-1] > cnt[i]
m[i-1] cnt[i-1] - cnt[i].
.
, , , .
, .
:
void findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, curCnt;
unsigned *cnt = (unsigned *) malloc(size * sizeof(*cnt));
for (i = 0; i < size; i++) cnt[i] = 1;
do {
for (curCnt = 0, i = 1; i < size; i += 2) {
if (m[i - 1] == m[i]) {
cnt[curCnt] = cnt[i - 1] + cnt[i];
m[curCnt++] = m[i];
}
else if (cnt[i] > cnt[i - 1]) {
cnt[curCnt] = cnt[i] - cnt[i - 1];
m[curCnt++] = m[i];
}
else if (cnt[i] < cnt[i - 1]) {
cnt[curCnt] = cnt[i - 1] - cnt[i];

7 -

442

m[curCnt++] = m[i - 1];


}
}
if (size & 1) {
cnt[curCnt] = cnt[i - 1];
m[curCnt++] = m[i - 1];
}
size = curCnt;
} while (size > 1);
free(cnt);
*majority = m[0];
}

major11.c
(n) (
2.1.). . , .

. , . ,
,
. .
. , . ,
, . ,
,
. ,
.

, :
ABC(: )
BC (: )
C (: )

(: C)
,
. , ,
, . ,
.
, -. :
/* , */
#define STACK_SIZE 100
CDataType stack[STACK_SIZE];
unsigned stIndex;
void stackInit(void) { stIndex = 0; }
void stackPush(CDataType elem) { stack[stIndex++] = elem; }
CDataType stackPop(void) { return stack[--stIndex]; }
CDataType stackTop(void) { return stack[stIndex - 1]; }
char stackIsEmpty(void) { return 0 == stIndex; }
char findMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned i, cnt;
stackInit();
for (stackPush(m[0]), i = 1; i < size; i++) {
if (stackIsEmpty())
stackPush(m[i]);
else if (stackTop() == m[i])

7 -

443

stackPush(m[i]);
else
stackPop();
}
if (stackIsEmpty()) return 0;
for (*majority = stackPop(), i = cnt = 0; i < size; i++)
if (m[i] == *majority)
cnt++;
return(cnt > size / 2);
}

major12.c
? ,
. ,
(, ), , .
: ( , ).
, 0.
:
1)
2)

0, , 1.
0:
2.1) , 1.
2.2) , 1.

.
0, . 0, ,
. ,
, .
, .
A A A C C B B C C C B C C
^
?:0
A A A C C B B C C C B C C
^
A:1
A A A C C B B C C C B C C
^
A:2
A A A C C B B C C C B C C
^
A:3
A A A C C B B C C C B C C
^
A:2
A A A C C B B C C C B C C
^
A:1
A A A C C B B C C C B C C

7 -

444

^
?:0
A A A C C B B C C C B C C
^
B:1
A A A C C B B C C C B C C
^
?:0
A A A C C B B C C C B C C
^
C:1
A A A C C B B C C C B C C
^
C:2
A A A C C B B C C C B C C
^
C:1
A A A C C B B C C C B C C
^
C:2
A A A C C B B C C C B C C
^
C:3

C . , C A, C
, . . .
, , .
:
char FindMajority(CDataType m[],unsigned size,CDataType *majority)
{ unsigned cnt, i;
for (i = cnt = 0; i < size; i++) {
if (0 == cnt) {
*majority = m[i];
cnt = 1;
}
else if (m[i] == *majority)
cnt++;
else
cnt--;
}
if (cnt > 0) {
for (i = cnt = 0; i < size; i++)
if (m[i] == *majority)
cnt++;
return(cnt > size / 2);
}
return 0;
}

major13.c

7 -

445

, , , ( ) . , , .
, .
, .
, , .
. ,
, .
, , ,
, ,
. ,
- (: ABC, C ).
. ,
.
, ,
. , -
, , , , -
. , 2n, , ,
, 5,43n163, n > 32. n 1
, 6,43n 164, n > 32. ( 7.1.)
:
1. , , , ,
.
2. , x
, x .
3. , m[] , , m[i] m[j] , .
4. , , ,
,
, .

7.3.
A B, a[]. , C
. , , . .
a[]. , . ,
,
. ,
b[], a[],
a[].
- a[] b[] ( n
m ) c[]. : 3
: . a[] b[]
- c[], c[] ,
- .
- c[], . ,
c[].
( while- memcpy()) :

7 -

446

i = j = k = 0;
while (i < n && j < m)
c[k++] = (a[i] < b[j]) ? a[i++] : b[j++];
if (i == n)
while(j < m)
c[k++] = b[j++];
else
while(i < n)
c[k++] = a[i++];

,
while-.
( - ) a[] b[],
. ,
a[] b[]:
i = j = k = 0; a[m] = b[n] = INFINITY; mn = m + n;
while (k < mn)
c[k++] = (a[i] < b[j]) ? a[i++] : b[j++];

n + m ,
-, memcpy(). , memcpy()
, ,
, (
):
i = j = k = 0;
while (i < n && j < m)
c[k++] = (a[i] < b[j]) ? a[i++] : b[j++];
if (i == n)
memcpy(c+k,b+j,m-j);
else
memcpy(c+k,a+i,n-i);

-
, A B C , . . C, C.
, ,
A B .
,
- , i j
. - . ( ), .
. .
,
. struct CElem
key.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MAX
12
#define ARRAYS 6

7 -
struct CElem {
int key;
/* */
};
struct CList {
unsigned len, point;
struct CElem data[MAX];
struct CList *next;
};
struct CList *init(unsigned mod) /* */
{ struct CList *head, *p;
unsigned i, j;
srand(time(NULL));
for (head = NULL, i = 0; i < ARRAYS; i++) {
p = (struct CList *) malloc(sizeof(struct CList));
p->len = MAX;
p->point = 0;
p->data[0].key = (rand() % mod);
for (j = 1; j < MAX; j++)
/* */
p->data[j].key = p->data[j-1].key + (rand() % mod);
p->next = head;
head = p;
}
return head;
}
void merge(struct CList *head)
{ struct CList *p, *q, *pMin;
struct CElem k1, k2;
int i;
printf("\n");
p = (struct CList *) malloc(sizeof(struct CList));
p->next = head;
head = p;
for (i = 0; i < MAX*ARRAYS; i++) {
p = head; pMin = head;
while (NULL != p->next) {
k1 = p->next->data[p->next->point];
k2 = pMin->next->data[pMin->next->point];
if (k1.key < k2.key)
pMin = p;
p = p->next;
}
printf("%8d", pMin->next->data[pMin->next->point].key);
if (pMin->next->len-1 == pMin->next->point) {
q = pMin->next;
pMin->next = pMin->next->next;
free(q);
}
else
pMin->next->point++;
}
}
void print(struct CList *head)
{ unsigned i;

447

7 -

448

for (; NULL != head; head = head->next) {


for (i = 0; i < MAX; i++)
printf("%6d", head->data[i].key);
printf("\n");
}
printf("\n");
}
int main(void)
{ struct CList *head;
head = init(500);
printf("\n :\n");
print(head);
printf(" :");
merge(head);
return 0;
}

mergearr.c
a1,a2,a3,a4,a5 | a6,a7,a8,a9,a10 | a11,a12,a13,a14,a15 | a16,a17,a18,a19,a20
b1

b2

b3

, merge() n + m (m n
). m n . m = n
2n1 . m = 1? ,
( 4.3.) , B1,
- log2 n , (n+1).
, , :
, , - ,
m = 1 , m = n .
7.3. .
C - . ,
n > m A m + 1 () . Bm Ak A. Bm Ak , Ak C, , Ak , . .
. (Bm Ak )
Bm , C Bm Bm A.
- , 2,
2log2n/m , n/m.
, C. ( 7.3.)
,
binaryMerge(), . a[] b[],
m n , c[], :
int binarySearch(struct CElem m[], int left,
int right, struct CElem elem)
{ int middle;
do {
middle = (left + right) / 2;
if (m[middle].key < elem.key)

7 -

449

left = middle + 1;
else
right = middle - 1;
} while (left <= right);
return right;
}
void binaryMerge(struct CElem a[], struct CElem b[],
struct CElem c[], int n, int m)
{ int t, t2, cind, k, j;
cind = n + m;
while (n > 0 && m > 0) {
if (m <= n) {
t = (int) (log(n / m) / log(2));
t2 = 1 << t; /* T2 <-- 2^T */
if (b[m - 1].key < a[n - t2].key) {
/* a[n-t2-1],...,a[n] */
cind -= t2;
n -= t2;
for (j = 0; j < t2; j++)
c[cind + j] = a[n + j];
}
else {
k = binarySearch(a, n - t2, n - 1, b[m - 1]);
for (j = 0; j < n - k - 1; j++)
c[cind - n + k + j + 1] = a[k + j + 1];
cind -= n - k - 1;
n = k + 1;
c[--cind] = b[--m];
}
}
else {
t = (int) (log(m / n) / log(2));
t2 = 1 << t; /* T2 <-- 2^T */
if (a[n - 1].key < b[m - t2].key) {
/* b[m-t2-1],...,b[m] */
cind -= t2;
m -= t2;
for (j = 0; j < t2; j++)
c[cind + j] = b[m + j];
}
else {
k = binarySearch(b, m - t2, m - 1, a[n - 1]);
for (j = 0; j < m - k - 1; j++)
c[cind - m + k + j + 1] = b[k + j + 1];
cind -= m - k - 1;
m = k + 1;
c[--cind] = a[--n];
}
}
}
if (n == 0)
for (j = 0; j < m; j++)
c[j] = b[j];
else
for (j = 0; j < n; j++)
c[j] = a[j];
}

binmerge.c

7 -

450

:

, .. .

7.4.
, ,
. .
, (),
().
. ,
. ,
0 1 .
( 7.3.) ,
. a[],
, .
. ( 7.3.) .
b[] a[], . .
, - (
) ,
. :
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int a[MAX],
b[MAX];

/* - */
/* */

const unsigned n = 100; /* */


/* */
void generate(void)
{ unsigned i;
for (i = 0; i < n; i++)
a[i] = rand() % (2*n + 1);
}
/* */
void printList(void)
{ unsigned i;
for (i = 0; i < n; i++)
printf("%4d", a[i]);
}
/* */
void mergeSort(unsigned left,
{ unsigned i, j, k, mid;
if (right <= left) return;
mid = (right + left) / 2;
mergeSort(left, mid);
mergeSort(mid + 1, right);

unsigned right)
/* */
/* */
/* */

/* a[] b[] */

7 -

451

for (i = mid + 1; i > left; i--)


b[i - 1] = a[i - 1];
/* */
for (j = mid; j < right; j++)
b[right + mid - j] = a[j + 1]; /* */
/* a[] */
for (k = left; k <= right; k++)
a[k] = (b[i] < b[j]) ? b[i++] : b[j--];
}
int main(void) {
generate();
printf(" :\n");
printList();
mergeSort(0, n-1);
printf(" :\n");
printList();
return 0;
}

merge_a.c
.
.
a[] b[] b[] a[],
. , a[] ,
b[]: , (
b1[]), (b2[]). b1[],
a[] ( ).
b2[], a[] (
) .. 4
: a[]/b[] b[]/a[] / .
(-) . ,
. , .
struct list { /* */
int value;
struct list *next;
} *empty; /* */
const unsigned long n = 100;
struct list *merge(struct list *a, struct list *b)
{ struct list *head, *tail;
/* , */
tail = head = empty;
for (;;) {
if (a->value < b->value) {
tail->next = a;
a = a->next;
tail = tail->next;
if (NULL == a) {
tail->next = b;
break;
}
}
else {

7 -

452

tail->next = b;
b = b->next;
tail = tail->next;
if (NULL == b) {
tail->next = a;
break;
}
}
}
return head->next;
}

merge_l1.c
- .
.
, .
struct list *mergeSort(struct list *c, unsigned long n)
{ struct list *a, *b;
unsigned long i, n2;
/* : */
if (n < 2)
return c;
/* */
for (a = c, n2 = n / 2, i = 2; i <= n2; i++)
c = c->next;
b = c->next;
c->next = NULL;
/* , */
return merge(mergeSort(a, n2), mergeSort(b, n - n2));
}

merge_l1.c
.
NULL. z, next z, value ( INFINITY).
z.
- , mergeSort()
. .

, , -.
, :
1, 2. ,
. , NULL,
,
. next z z, .
:
#include <stdio.h>
#include <stdlib.h>
#define INFINITY (int)((1 << (sizeof(int)*8 - 1)) - 1)

7 -

const unsigned long n = 100;


struct list { /* */
int value;
struct list *next;
} *z; /* */
/* */
struct list *generate(unsigned long n)
{ struct list *p, *q;
unsigned long i;
for (p = z, i = 0; i < n; i++) {
q = (struct list *) malloc(sizeof(struct list));
q->value = rand() % (2*n + 1);
q->next = p;
p = q;
}
return p;
}
void printList(struct list *p) /* */
{ for (; p != z; p = p->next)
printf("%4d", p->value);
}
struct list *merge(struct list *a, struct list *b)
{ struct list *c;
c = z;
/* , */
do {
if (a->value < b->value) {
c->next = a;
c = a;
a = a->next;
}
else {
c->next = b;
c = b;
b = b->next;
}
} while (c != z);
c = z->next;
z->next = z;
return c;
}
struct list *mergeSort(struct list *c)
{ struct list *a, *b;
/* : */
if (c->next == z)
return c;
/* */
for (a = c, b = c->next->next->next; b != z; c = c->next)
b = b->next->next;
b = c->next;
c->next = z;

453

7 -

454

/* , */
return merge(mergeSort(a), mergeSort(b));
}
int main(void) {
struct list *l;
/* z */
z = (struct list *) malloc(sizeof(struct list));
z->value = INFINITY;
z->next = z;
l = generate(n);
printf(" :\n");
printList(l);
l = mergeSort(l); /* , 1 . */
printf(" :\n");
printList(l);
return 0;
}

merge_l2.c
, .
.
.
. mergeSort()
, .
. for.
, ,
.. ,
, -
. .
. todo .
while , ,
. .

. [Sedgewick-1992]
struct list *mergeSort(struct list *c)
{ unsigned long i, n, n2;
struct list *a, *b, *head, *todo, *t;
head = (struct list *) malloc(sizeof(struct list));
head->next = c;
a = z;
for (n = 1; a != head->next; n <<= 1) {
todo = head->next;
c = head;
while (todo != z) {
t = todo;
/* a[] */
for (a = t, i = 1; i < n; i++)
t = t->next;
/* b[] */
b = t->next; t->next = z;
for (t = b, i = 1; i < n; i++)

7 -
t = t->next;
/* a[] b[]
todo = t->next; t->next
c->next = merge(a, b);
/*
for (n2 = n + n, i = 1;
c = c->next;

455

*/
= z;
*/
i <= n2; i++)

}
}
return head->next;
}

merge_l3.c
? , (n.log2
n). - ,
( 3.1.10.). 3.2., () ,
. , .
( 3.1.9.) ( 3.1.6.) , .
, , - ( - ). - (n2), - , 3.1.4. (, , .) (n.log2
n), - ,
.
, ,
n: .
, (
[-1980]). ,
, - , , n.
,
, , . ,
, . . .
. . ,
, ,
.
.
,
. ,
. ,
15-20 ( )
( 3.1.2.).
:
1.
: 100; 1000; 10000; 100000 .

7 -

456

2. ,
:
) 3
) k , k > 3
3. :
) -
) -
- - .
4. ,
.
5. ,
.
6. , :
)
)
)
7. ,
( 7.3.).

7.5.
1.1.1. xn (x , n ). - ( - ), [-1995]:

n2 n2

x x .x , n
n 1

x .x, n
n

, ,
: ,
( ). , , .
.
#include <stdio.h>
const double base = 3.14;
const unsigned d = 11;
double power(double x, unsigned n)
{ if (0 == n) return 1;
else
if (n % 2) return x * power(x, n - 1);
else return power(x * x, n / 2);
}
int main(void) {
printf("%lf^%u = %lf\n", base, d, power(base, d));
return 0;
}

powrec.c

7 -

457

,
. , n = 15 -
:
1) x1
2) x2 = x1.x1
3) x3 = x2.x1
4) x6 = x3.x3
5) x7 = x6.x1
6) x14 = x7.x7
7) x15 = x14.x1
. . 7 . , :
1) x1
2) x 2 = x 1.x1
3) x 3 = x2. x1
4) x 4 = x3. x1
5) x 7 = x4. x3
6) x 8 = x7. x1
7) x15 = x8. x7
- 6 , :
1) x1
2) x2 = x1.x1
3) x3 = x2.x1
4) x5 = x3.x2
5) x10 = x5.x5
6) x15 = x10.x5
:
1) x1;
2) x2 = x1.x1;
3) x4 = x2.x2;
4) x5 = x4.x1;
5) x10 = x5.x5;
6) x15 = x10.x5
:
1, 2, 3, 4, 7, 8, 15
1, 2, 3, 5, 10, 15
1, 2, 4, 5, 10, 15
, 1,
. .
, , ,
. [-1998]
:
( 9), , - , -.

7 -

458

7.6.


. , A
= (aij)mn B = (bij)nr :
n

cij aik bkj


k 1

nn C (n3): n2 (n).
, , ,
(1), n.
, ,
. 60- , (nlog7).
,
.
, ,
, .
.
A B 2 2:
c11 c12 a11 a12 a11 a12

c21 c22 a21 a22 a21 a22


, :
cij = ai1b1j + ai2b2j, i = 1,2 j = 1,2
, 8 4 . ,
7 ( Pi
):
P1 = (a11 + a22)(b11 + b22)
P2 = (a21 + a22)b11
P3 = a11(b12 b22)
P4 = a22(b21 b11)
P5 = (a11 + a12)b22
P6 = (a21 a11)(b11 + b12)
P7 = (a12 a22)(b21 + b22)
c11 = P1 + P4 P5 + P7
c12 = P3 + P5
c21 = P2 + P4
c22 = P1 + P3 P2 + P6
, , : ( ) 18.
, , -
(- ) /.
. . . ,
, . ,
. , ,

7 -

459

.
( [Brassard, Bratley-1987]):
P1 = (a21 + a22 a11) (b22 b12 + b11)
P2 = a11b11
P3 = a12b21
P4 = (a11 a21)(b22 b12)
P5 = (a21 + a22)(b12 b11)
P6 = (a12 a21 + a11 a22)b22
P7 = a22(b11 + b22 b12 b21)
c11 = P2 + P3
c12 = P1 + P2 + P5 + P6
c21 = P1 + P2 + P4 P7
c22 = P1 + P2 + P4 + P5
, , .
, ([Aho, Hopcroft, Ullman-1987]):
P1 = (a12 a22)(b21 + b22)
P2 = (a11 + a22)(b11 + b22)
P3 = (a11 a21)(b11 + b12)
P4 = (a11 + a12)b22
P5 = a11(b12 b22)
P6 = a22(b21 b11)
P7 = (a21 + a22)b11
c11 = P1 + P2 P4 + P6
c12 = P4 + P5
c21 = P6 + P7
c22 = P2 P3 + P5 P7
aij, bij cij nn, ,
2n, 7, 8
nn. - . , n2 , n3
n3 . . . .
? n ,
(n/2)(n/2). , n 2,
22. ,
7 . T(n)
n, 2, :
T(n) = 7T(n/2) + 18(n/2)2, n > 2
( 1.4.10.) T(n) (nlog7). log 7 2,81 < 3,
.. - .
, , n 2? - n,
2. . -
. , , - 7 .

. ? : ,
7 . : n = 2

7 -

460

, . n = 3, 4, ? (
n) ?
(n 2) , . . . n , . n/2 , ,
.
, . .
,
. :
. .
n . ( 7.6.)

11
21

12

22

B11
b21

b12

b22

7.6. A B.
C11 ( 7.6.).

C11
c 21


c12



c 22

A11B11 a12b21
a 21B11 a 22b21

A11b12 a 21b22

a 21b12 a 22b22

7.6. C A B.
,
n.
,
. 1996 ,
- . , ,
- .
.
/ 18 15, .
:
S1 = a21 + a22
S2 = S1 a11
S3 = a11 a21
S4 = a12 S2
T1 = b12 b11
T2 = b22 T1
T3 = b22 b12
T4 = b21 T2
P1 = a11b11

7 -

461
P2 = a12b21
P3 = S1T1
P4 = S2T2
P5 = S3T3
P6 = T4b22
P7 = a22T4
U1 = P 1 + P 4
U2 = U1 + P 5
U3 = U1 + P 3
c11 = P1 + P2
c21 = U2 + P7
c22 = U2 + P3
c12 = U3 + P6


n = 2, . 1971 .
, , ( .). - 33
- 21 , (nlog3 21), . . (n2,771244).
- -
. ,
7070 143 640 ( 343 000,
). - - -
: (n2,521813) 1979 ., (n2,521801) 1980 ., (n2,376) 1986 .
:
1. .
2. .
3. .

7.7.
, ,
(n2) n- (, , n).
,
.
. , n- X Y, , n 2 ( , ). X Y ,
A, B C, D n/2 , :
X = 2n/2.A + B
Y = 2n/2.C + D
XY :
XY = 2n.AC + 2n/2.(AD+BC) + BD
, XY 4
n/2 , 3 - n+1 n/2

7 -

462

( 2n 2n/2). AC, AD, BC BD


,
, :
T(1) = 1
T(n) = 4T(n/2) + cn, n > 1 n 2
(. 1.4.10.), T(n) (n2), . .
, , : . - (
7.6.), .
. - ,
, AD BC:
. :
XY = 2n.AC + 2n/2.[(AB)(DC) + AC + BD] + BD
3 , 6 ( 2 ) 2 .
(,
, . . n = 1, ):
T(1) = 1
T(n) = 3T(n/2) + cn, n > 1 n 2
( 1.4.10.) T(n) (nlog23). log2 3 1,59 < 2,
. . - . , , :
XY = 2n.AC + 2n/2.[(A+B)(C+D) AC BD] + BD
, (. . ), . ( , 2,
. .) o
. , X Y ,
n 2. n = 1 .
[Aho,Hopcroft,Ullman1987]
int mult (int X,
{
int s;
int m1,m2,m3;
int A,B,C,D;

Y, n)
/* XY */
/* */
/* X Y */

/* */
if (1 == n)
return (X*Y);
s = sign(X) *sign(Y);
X = abs(X);
Y = abs(Y);
A = n/2 X;
B = n/2 X;
C = n/2 Y;
D = n/2 Y;
m1 = mult(A,C,n/2);
m2 = mult(A-B,D-C,n/2);
m3 = mult(B,D,n/2);

/* *** */

7 -

463

return s * (m1<<n + (m1+m2+m3)<<(n/2) + m3); /* *** */


}

, ,
/* *** */, :
m2 = mult(A+B,C+D,n/2);
/* *** */
return s * (m1<<n + (m2-m1-m3)<<(n/2) + m3); /* *** */

, n 2? n ,
. n/2 , , . .
, ,
(nlog23).
, -, ,
n/2- n- , (n+1)-.
(A+B)(C+D), , (n+1) ( AC BD .). X = 9999 Y = 9998.
:
A = 99, B = 99, C = 99 D = 98
AC = 99.99 = 9801
BD = 99.98 = 9702
(A+B)(C+D) = 198.197 = 39006
(. . 5- )
- 1
(nlog23). .
[Brassard, Bratley 1987].
, m n, m n?
, m < n. - ,
(nlog23) (mn) . , - , m < n(log23)1. - m.
, n/m .
(mn(log23)1).
: ,
? : - - , - .
. , , , - 500 .
:
1. .
2.
- .
3. ,
, . , 5 ( 9)
n/3 .
.
4. , 2k1
k .

7 -

464

,
(nx) x > 1.

7.8.
: n A, B C.
. (
7.8.)
:
1. .
2. - -.
, ,
- . ,
, [-1993],
.

7.8. .
1
. , , n
a A C, n1 A B,
n ( - ) A
C n1 B C.
- (),
, ( - )
(). :
#include <stdio.h>
const unsigned n = 4;
void diskMove(unsigned n, char a, char b)
{ printf(" %u %c %c.\n", n, a, b); }
void hanoy(char a, char c, char b, unsigned numb)
{ if (1 == numb)
diskMove(1, a, c);
else {
hanoy(a, b, c, numb - 1);
diskMove(numb, a, c);
hanoy(b, c, a, numb - 1);
}
}
int main(void) {
printf(" : %u\n", n);

7 -

465

hanoy('A', 'C', 'B', n);


return 0;
}

hanoy.c
n = 2, 3 4:
: 2
1 A B.
2 A C.
1 B C.
: 3






1
2
1
3
1
2
1

A
A
C
A
B
B
A

C.
B.
B.
C.
A.
C.
C.

: 4














1
2
1
3
1
2
1
4
1
2
1
3
1
2
1

A
A
B
A
C
C
A
A
B
B
C
B
A
A
B

B.
C.
C.
B.
A.
B.
B.
C.
C.
A.
A.
C.
B.
C.
C.

-
.
, ,
, . ,
1. .
2
:
1. n , ,
. n .
2. .
3. - -.
3
:
1. -
n () ().
2. ,
- .
3. - -.

7 -

466

4

. n C, ; n B .
1. , -
- -. e
, - . , .
2.
.
:
1. 2, 3 4.
2. , 2, 3 4 1.

7.9.
, ,
. :
(III '95)
n ( 1 n). n , n
, n1 , . .
, .
n . j-
i- , i
j. ( i k j, , k
i .)
i j- , j- i- 0.
, n = 3 n = 4 ( :
, : ):
2
1
0

3
0
1

0
3
2

2
1
4
3

3
4
1
2

4
3
2
1

: . , nn ( n), "-", i- j- , i j (1 i, j n).


.
n = 1. n = 2 ,
: 7.9.

1
2

1
0
1

2
1
0

7.9. 2 .
i:j, , i j (1 i, j n). 3 .

7 -

467

? , 1:2 3:4,
1:3 2:4, 1:4 2:3. 7.9.

1
2
3
4

1
0
1
2
3

2
1
0
3
2

3
2
3
0
1

4
3
2
1
0

7.9. 4 .
- , n = 2
2 3
3 2

,
0 1
1 0

2.
n = 8? n = 4, 4 4 . ( 7.9.)

1
2
3
4
5
6
7
8

1
0
1
2
3
4
5
6
7

2
1
0
3
2
5
4
7
6

3
2
3
0
1
6
7
4
5

4
3
2
1
0
7
6
5
4

5
4
5
6
7
0
1
2
3

6
5
4
7
6
1
0
3
2

7
6
7
4
5
2
3
0
1

8
7
6
5
4
3
2
1
0

7.9. 8 .
, 7.9. :
0 7 , . .
7 , . , .
. i:j, j:i, (1 i, j n). , . .
i:i, 1 i n. n = 16, 32, 64, n,
2. .
. . n = 2k . n,
n/2 (), 4
(). .
#include <stdio.h>
#define MAX 100
unsigned m[MAX][MAX];
void copyMatrix(unsigned stX, unsigned stY, unsigned cnt, unsigned add)
{ unsigned i, j;
for (i = 0; i < cnt; i++)

7 -

468

for (j = 0; j < cnt; j++)


m[i + stX][j + stY] = m[i + 1][j + 1] + add;
}
void findSolution(unsigned n) /* */
{ unsigned i;
m[1][1] = 0;
for (i = 1; i <= n; i <<= 1) {
copyMatrix(i + 1, 1, i, i);
copyMatrix(i + 1, i + 1, i, 0);
copyMatrix(1, i + 1, i, i);
}
}
void print(unsigned n)
/* */
{ unsigned i, j;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
printf("%3u", m[i][j]);
printf("\n");
}
}
int main(void) {
const unsigned n = 8;
findSolution(n);
print(n);
return 0;
}

tourn1.c
, n, 2. , n. , n.
n : nn,
, . . n(n+1). , - . (n+1)-
, . 1
1 1,
[1;n]. n 1. 7.9.
n = 5. , , (n+1)-
. (?)

1
2
3
4
5
6
1
2
3
4
5
1
1
2
3
4
5
1
2
2
3
4
5
1
2
3
3
4
5
1
2
3
4
4
5
1
2
3
4
5
5
7.9. 5 .
( 7.9.).

1
0

2
2

3
3

4
4

5
5

6
1

7 -

469
2
3
4
5

2
3
4
5

0
4
5
1

4
0
1
2

5
1
0
3

1
2
3
0

2
3
4
5

7.9. 5 .
n .
. n1, , , , n- : m[k][k], k n-, n .
, n = 4, n = 3
( 7.9.).

1
2
3

1
1
2
3

2
2
3
1

3
3
1
2

4
1
2
3

7.9. 3 .

1
2
3
4

1
0
2
3
1

2
2
0
1
2

3
3
1
0
3

4
1
2
3
0

7.9. 4 .
n- ,
7.9. findSolution():
void findSolution(unsigned n) /* */
{ unsigned i;
unsigned saveN = n;
if (n % 2 == 0) /* n , n-1 */
n--;
/* n - . */
for (i = 0; i < n * (n + 1); i++)
m[i % (n + 1)][i / (n + 1)] = i % n + 1;
/* n */
n = saveN;
for (i = 0; i < n; i++) {
if (n%2 == 0) /* , n */
m[i][n - 1] = m[n - 1][i] = m[i][i];
m[i][i] = 0;
/* 0 */
}
}

tourn2.c

7 -

470

, , :
i j? . - ,
.
(n = 2k). A B s t, n. s + t 1, s + t n, s + t n, s + t > n.
.
: - ,
s + t . n , l 2l 1,
2l n 2l n, 2l > n. 1
n/2 , . .
-
i j?, ,
. . :
void findSolution(unsigned n) /* */
{ unsigned i, j;
unsigned saveN = n;
if (n % 2 == 0) /* n , n-1 */
n--;
/* n - . */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if ((m[i][j] = i + j + 1) > n)
m[i][j] -= n;
/* n */
n = saveN;
for (i = 0; i < n; i++) {
if (n % 2 == 0) /* , n */
m[i][n - 1] = m[n - 1][i] = m[i][i];
m[i][i] = 0;
/* 0 */
}
}

tourn3.c
, 0, 1.
:
1. ,
.
2.
n 2.
3. ,
n .
4.
n, n 2.
5. .

7 -

471

7.10.

UNIX .
,
. ,
, . , , , , - .
- ,
-. m, n.
? ,
: , .
. ,
1
1. k m x.
2. nk k .
3. x m ( k ).
. , k = 1
shiftBy1(), (n). :
2
1. k shiftBy1().
, , , -
(n2).
, ,
, ? ,
. m[] tmp,
m[k+1] m[1], m[2k+1] m[k+1] . .,
m[] n. m[1],
tmp. , ,
, m[2] ..
( , 0.):
#include <stdio.h>
#define MAX 100
struct CElem {
int data;
/* ... */
} m[MAX];
const unsigned n = 10; /* */
const unsigned k = 2; /* */

7 -

472

void init(void)
{ unsigned i;
for (i = 0; i < n; i++)
m[i].data = i;
}
unsigned gcd(unsigned x, unsigned y)
{ while (y > 0) {
unsigned tmp = y;
y = x % y;
x = tmp;
}
return x;
}
void shiftLeft1(unsigned k)
{ /* m[] k , */
unsigned i, ths, next, gcdNK;
struct CElem tmp;
for (gcdNK = gcd(n, k), i = 0; i < gcdNK; i++) {
ths = i; tmp = m[ths];
next = ths + k;
if (next >= n)
next -= n;
while (next != i) {
m[ths] = m[next];
ths = next;
next += k;
if (next >= n)
next -= n;
}
m[ths] = tmp;
}
}
void print(void)
{ unsigned i;
for (i = 0; i < n; i++)
printf("%d ", m[i].data);
printf("\n");
}
int main(void) {
init();
shiftLeft1(k);
print();
return 0;
}

shift1.c
. A k m, B nk. m k AB BA. , k < n/2, . . A -
B. B BL BR, BR k , . . , A.

7 -

473

ABLBR BLBRA.
A BR ( k ), A . BL BR B. B , , - .
, : .
,
. :
void swap(unsigned a, unsigned b, unsigned l)
{ /* m[a..a+l-1] m[b..b+l-1] */
unsigned i;
struct CElem tmp;
for (i = 0; i < l; i++) {
tmp = m[a + i];
m[a + i] = m[b + i];
m[b + i] = tmp;
}
}
void shiftLeft2(unsigned k)
{ /* m[] k .
* , } */
unsigned i, j, p;
p = i = k;
j = n - k;
while (i != j)
if (i > j) {
swap(p - i, p, j);
i -= j;
}
else {
swap(p - i, p + j - i, i);
j -= i;
}
swap(p - i, p, i);
}

shift2.c
, , . ,
, :
BA = (ARBR)R.
AR - , A, . BR (ARBR)R.
, : BA A,
B, . :
void reverse(unsigned a, unsigned b) /* m[a..b] */
{ unsigned i, j, k, cnt;
struct CElem tmp;
for (cnt = (b-a)/2, k=a, j=b, i=0; i <= cnt; i++, j--, k++) {
tmp = m[k];
m[k] = m[j];
m[j] = tmp;

7 -

474

}
}
void shiftLeft3(unsigned k)
{ /* m k , */
reverse(0, k - 1);
reverse(k, n - 1);
reverse(0, n - 1);
}

shift3.c

(n). , - n , n. ,
ShiftLeft1() ,
ShiftLeft3() ( [Bentley-1990], [1998d]).
:
1. shiftLeft1(), shiftLeft2()
shiftLeft3().

2. BA = (ARBR)R.

7.11.

. - - .
.
: nn, n 2. .
, 22, .
,
.
: , .
, 22k 1 3
k, k > 0. : (2k 1)(2k +1). 2k 1, 2k 2k +1. , . .
3, 2k . 2k 1 2k +1. (2k 1)(2k +1) = 22k 1 3. . .
3 ,
, , 3. ,
.
, n = 2k , ( k).
1) : k = 0 n = 1 ,
k = 1, . . n = 2, , .
2) : , k, . . 2k 2k , .
3) : , k+1, . .
2k+12k+1, .

7 -

475

, .
2k 2k , .
, , ,
.
2k 2k .
, ,
( 7.11.).

7.11. .
.
.
:
.

7.12.
7.12.1.
7.1.
k- ( 7.1.),
.
7.2.
, k- ,
, ,
i, j k, 7.1., 7.1. 7.1.
7.3.
k-
, , ( 7.1.).
7.4.
5
( 7.1.)? 3?
? .
7.5.
( 7.1.).
7.6.
, , , ,
( 7.2.).

7 -

476

7.7.
, x
, x ( 7.2.).
7.8.
, m[] , , m[i] m[j] , (
7.2.).
7.9.
, , , , ,
( 7.2.).
7.10.

, .. ( 7.3.).
7.11.

: 100; 1000; 10000; 100000 ( 7.4.).
7.12.
( 7.4.),
:
) 3
) k , k > 3
7.13.
(
7.4.):
) -
) -
- - .
7.14.
, ( 7.4.).
7.15.
, ( 7.4.)
.
7.16.
( 7.4.),
:
)
)
)
7.17.
( 7.4.),
( 7.3.).
7.18.
( 9), , - , 7.5.

7 -

477

7.19.
( 7.6.).
7.20.
( 7.6.).
7.21.
( 7.6.).
7.22.
( 7.7.).
7.23.

- ( 7.7.).
7.24.
,
, . , 5 ( 9)
n/3 . ( 7.7.).
7.25.
, 2k1
k .
,
(nx) x > 1.
7.26.
2, 3 4 7.8.
7.27.
, 2, 3 4 7.8.
1.
7.28.
7.9. ,
.
7.29.
7.9.
n 2.
7.30.
7.9. ,
n .
7.31.
7.9. n, n 2.
7.32.
7.9. .

7 -

478

7.33.
shiftLeft1(), shiftLeft2()
shiftLeft3() 7.10.
7.34.
BA = (ARBR)R 7.10.
7.35.
7.11.

7.12.2.
7.36. -
( 7.1.), ( 3.1.6.) , (n.log2 n).
(
3.1.9.).
7.37. k-
k- - .
:
k
k- x ( 7.1.),
x
( ) k-
.
7.38. -
n , . ,
.
? n-?
7.39.
n , .
( ), .
? n-?
7.40.
, - ? ?

( 3.1.6.)
( 3.1.9.), (?)
( 3.2.3.),
( 4.3.)
( 4.4.)
( 4.5.)
- ( 10.4.1.)
( 10.4.2.)

7 -

479

8

"A mind that is stretched
to a new idea never returns
to its original dimension."
~ Oliver Wendell Holmes

8.1.
- ( ), -. - -
,
.
. - ,
:
. ,
-
( 7).
, , , ,

. - (
), . -
- .
, :
, ..
, .
,
.
, , -
. ,
, .
, ,
,
.
( 1.2.2.):
unsigned long fib(unsigned n)
{ if (n < 2) return n;
else return fib(n-1) + fib(n-2);
}

, , ?
. ,
fib(n) n,

8 -

482

, , .
.
8.1. ,

.

, n- ( 8.3.1.), . , ,
.
(. dynamic
programming), -. ,
. ,
- .

, .
.
, ( ) . .
,
.
.
, ( SAP Microsoft).
, . .
. ( , 8.3.1),
( , 8.2.1.), ( , 8.2.3.), -.
, .
. ,
, , , , . , , : ,
, -
, .
:
. , .
, .
, ( 8.2.3.)
, , .
, - .
.
, ,
. -
, - .
, .

8 -

483

, , , . (?)
, , . , (, .),
, , .
.
-, .
. (, , ), - ,
.. , ,
- , ,
, . - . . .
,
memoization. ,
: -.
.
,
, , . , ,
, .
, .
, , .
. "" -
,
( 6.3.).
.
,
. :
-, -.
. - -.
,
, . .
. ( , -, ,
, ,
. , ,
, .)
, , .
.
- ,
.
,
. -.
, - .
, .
- .
, - ,
. -
, ,
- .

8 -

484

:
1. ,
?
2. , .
3. ?

8.2.
8.2.1.
- , . , (
6.4.1 9.1.5.). -
(0-1 ) ,
. .
M N ,
mi ci. , , M. M, N, ci mi (1 i N).
:
N

x c
i 1

i i

:
N

x m
i 1

M,

ci 0, mi 0, xi 0,1, i 1,2,..., n
ci mi ( ), xi
.
: F(i), i.

F (i)
max c j F (i m j )

j 1, 2,...,N ;m j i

i0
i0

, ,
F. ,
. - F(i) set[i],
, .
,
, set[i] .
, (memoization).
,
NOT_CALCULATED . ,
F(i) i = 1, 2, , N, Fn[i]
( ) NOT_CALCULATED,

8 -

485

Fn[i] .
F(). .
F(), .
, calculate(),
, ,
F().
:
#include <string.h>
#include <stdio.h>
#define NOT_CALCULATED (unsigned) (-1)
#define MAXN
30 /* */
#define MAXM
1000 /* */
char set[MAXM][MAXN];
unsigned Fn[MAXM];
const
const
const
const

unsigned
unsigned
unsigned
unsigned

/* k = 1..M */
/* */

m[MAXN] = {0,30,15,50,10,20,40,5,65};
/*
c[MAXN] = {0,5,3,9,1,2,7,1,12};
/*
M = 70;
/*
N = 8;
/*

*/
*/
*/
*/

/* k */
void F(unsigned k)
{ unsigned i, bestI, fnBest, fnCur;
/* - F */
for (bestI = fnBest = 0, i = 1; i <= N; i++) {
if (k >= m[i]) {
if (NOT_CALCULATED == Fn[k - m[i]]) F(k - m[i]);
if (!set[k - m[i]][i])
fnCur = c[i] + Fn[k - m[i]];
else
fnCur = 0;
if (fnCur > fnBest) {
bestI = i;
fnBest = fnCur;
}
}
}
/* - */
Fn[k] = fnBest;
if (bestI > 0) {
memcpy(set[k], set[k - m[bestI]], N);
set[k][bestI] = 1;
}
}
/* */
void calculate(void) {
unsigned i, sumM;
/* */
memset(set,0,sizeof(set)); /* . */
for (i = 0; i <= M; i++) /* . */
Fn[i] = NOT_CALCULATED;
/* ? */
for (sumM = m[1], i = 2; i <= N; i++) sumM += m[i];

8 -

486

if (M >= sumM) {
printf("\n !");
return;
}
else {
F(M); /* */
/* */
printf("\n :\n");
for (i = 1; i <= N; i++)
if (set[M][i])
printf("%5u", i);
printf("\n : %u", Fn[M]);
}
}
int main(void) {
printf("%s%u", "\n : ", N);
printf("%s%u", "\n : ", M);
calculate();
return 0;
}

knapsack 1.c
:
:
2
3
7
: 13

: ( ) , ,
1 (
). , N
( M) , MAXN MAXM.
, . ,
7 8, ,
, .

F(1), F(2), ..., F(M), . ,
, . . , .
. F()
Fn[] calculate().
void calculate(void)
{ unsigned maxValue;
/* */
unsigned maxIndex;
/* , */
unsigned i, j;
memset(set,0,sizeof(set)); /* . */
/* */
for (i = 1; i <= M; i++) { /* . Fn(i) */
maxValue = maxIndex = 0;
for (j = 1; j <= N; j++)
if (m[j] <= i && !set[i - m[j]][j])
if (c[j] + Fn[i - m[j]] > maxValue) {
maxValue = c[j] + Fn[i - m[j]];
maxIndex = j;
}

8 -

487

if (maxIndex > 0) { /* - i? */
Fn[i] = maxValue;
/* set[i] set[i-m[maxIndex]]
* maxIndex */
memcpy(set[i], set[i - m[maxIndex]], N);
set[i][maxIndex] = 1;
}
if (Fn[i] < Fn[i - 1]) { /* */
Fn[i] = Fn[i - 1];
memcpy(set[i], set[i - 1], N);
}
}
/* */
printf("\n :\n");
for (i = 1; i <= N; i++)
if (set[M][i])
printf("%5u", i);
printf("\n%s%u", " : ", Fn[M]);
}

knapsack2a.c
, calculate(), ( ), ,
.
- set[].
( char). . , , ,
8 . , .
, - . -
, . (memset() memcpy()) 8 - ,
. . -.
? j ,
F(i), - set[i][j] 1.
1 j%8 set[i][j].
set[i][j/8]&(1 << (j%8)). / () % ( ).
, . , 8 3 , 8 "" 7. set[i][j>>3]&(1<<(j&7)). , m[i][j] 1 set[i][j>>3] |= 1 << (j & 7). 8 - .
:
char set[MAXM][MAXN / 8]; /* k = 1..M */
void calculate(void)
{ unsigned maxValue;
/* */
unsigned maxIndex;
/* , */
unsigned i, j;
memset(set,0,sizeof(set)); /* . */

8 -

488

/* */
for (i = 1; i <= M; i++) { /* . F(i) */
maxValue = maxIndex = 0;
for (j = 1; j <= N; j++) {
if (m[j] <= i && !(set[i - m[j]][j >> 3] & (1 << (j & 7))))
if (c[j] + Fn[i - m[j]] > maxValue) {
maxValue = c[j] + Fn[i - m[j]];
maxIndex = j;
}
}
if (maxIndex > 0) { /* - i? */
Fn[i] = maxValue;
/* set[i] set[i-m[maxIndex]]
* maxIndex */
memcpy(set[i], set[i - m[maxIndex]], (N >> 3) + 1);
set[i][maxIndex >> 3] |= 1 << (maxIndex & 7);
}
if (Fn[i] < Fn[i - 1]) { /* */
Fn[i] = Fn[i - 1];
memcpy(set[i], set[i - 1], (N >> 3) + 1);
}
}
/* */
printf("\n :\n");
for (i = 1; i <= N; i++)
if (set[M][i >> 3] & (1 << (i & 7)))
printf("%5u", i);
printf("\n%s%u", " : ", Fn[M]);
}

knapsack2b.c
. . . F[i][j] (1 i < N, 0 j < M),

M. F[i][j] ,
, i , j.
F[N][M].
:
F[i][j] = max(F[i-1][j], F[i-1][j-mi]+ci)

. - :
, F[i][j], i.
F[i][j] F[i-1][j], F[i-1][j-mi]+ci.
, .
F[0][j] = 0, j = 0, 1, ..., M. :
unsigned F[MAXN][MAXM]; /* */
void calculate(void) /* */
{ unsigned i,j;
for (j = 0; j <= M; j++)
F[0][j] = 0;

8 -

489

for (i = 1; i <= N; i++)


for (j = 0; j <= M; j++)
if (j >= m[i] && F[i-1][j] < F[i-1][j-m[i]] + c[i])
F[i][j] = F[i-1][j-m[i]] + c[i];
else
F[i][j] = F[i-1][j];
}

knapsack3a.c
. ,
15 6 ,
( !):
const
const
const
const

unsigned
unsigned
unsigned
unsigned

m[MAXN] = {0,1,2,3,5,6,7};
/* */
c[MAXN] = {0,1,10,19,22,25,30}; /* */
M = 15;
/* */
N = 6;
/* */

knapsack3a.c
F[][],
calculate(). printTable():
void printTable(void) /* F[][] */
{ unsigned i, j;
for (i = 1; i <= N; i++) {
printf("\n");
for (j = 0; j <= M; j++)
printf("%4u",F[i][j]);
}
}

knapsack3a.c
N\M
1
2
3
4
5
6

0
0
0
0
0
0
0

1
1
1
1
1
1
1

2
1
10
10
10
10
10

3
1
11
19
19
19
19

4
1
11
20
20
20
20

5
1
11
29
29
29
29

6
1
11
30
30
30
30

7
1
11
30
32
32
32

8
1
11
30
41
41
41

9
1
11
30
42
44
44

10
1
11
30
51
51
51

11
1
11
30
52
54
54

12
1
11
30
52
55
59

13
1
11
30
52
57
60

14
1
11
30
52
66
66

15
1
11
30
52
67
71

8.2.1. knapsack3a.c.
8.2.1. . . ,
. F[6][15] F[5][15],
F[6][15] == F[5][15m6] + c6, , 6
. - F[5][8] == F[4][8] F[5][8] F[4][8m5] + c5,
, 5 .
F[4][8]. F[4][8] F[3][8], F[4][8] == F[3][8m4] + c4, . . 4
. F[3][3] F[2][3] F[3][3] == F[2][3m3] + c3 .. 3 . F[2][0].
0, . ( , F[2][0] = F[1][0] =
F[0][0]).
:
void printSet(void) /* , */

8 -
{

490

/* */
/* */
unsigned i = N,
j = M;
while (j != 0) {
if (F[i][j] == F[i-1][j])
i--;
else {
printf("%u ",i);
j -= m[i];
i--;
}
}

knapsack3a.c
: , .
-.
, 3, 4 6.
. , . ,
6.

, . ,
, . -
, -, .
. :
const
const
const
const

unsigned
unsigned
unsigned
unsigned

m[MAXN] = {0,6,3,10,2,4,8,1,13,3};
/* */
c[MAXN] = {0,5,3,9,1,2,7,1,12,3};
/* */
M = 14;
/* */
N = 9;
/* */

knapsack3b.c
13 , : {2, 3, 7}, {2, 6, 9}, {3, 7, 9} {7, 8}. ? 8.2.1., .
N\M
1
2
3
4
5
6
7
8
9

0
0
0
0
0
0
0
0
0
0

1
0
0
0
0
0
0
1
1
1

2
0
0
0
1
1
1
1
1
1

3
0
3
3
3
3
3
3
3
3

4
0
3
3
3
3
3
4
4
4

5
0
3
3
4
4
4
4
4
4

6
5
5
5
5
5
5
5
5
6

7
5
5
5
5
5
5
6
6
7

8
5
5
5
6
6
7
7
7
7

9
5
8
8
8
8
8
8
8
8

10
5
8
9
9
9
9
9
9
9

11
5
8
9
9
9
10
10
10
10

12
5
8
9
10
10
10
11
11
11

13
5
8
12
12
12
12
12
12
12

14
5
8
12
12
12
12
13
13
13

8.2.1. knapsack3b.c.
F[9][14] == F[8][14] F[9][14] == F[8][14m9] + c9. , 9 , .
- printSet() ,

8 -

491

F[8][14]. ,
, .
() set[],
. : i, j k. i j
F[][], k set[].
unsigned set[MAXN]; /* , max */
void printAll(unsigned i, unsigned j, unsigned k)
{ /* , */
/*
*/
if (0 == j) {
printf("\n : ");
for (i = 0; i < k; i++)
printf("%u ",set[i]);
}
else {
if (F[i][j] == F[i-1][j])
printAll(i-1,j,k);
if (j >= m[i] && F[i][j] == F[i-1][j-m[i]] + c[i]) {
set[k] = i;
printAll(i-1,j-m[i],k+1);
}
}
}
/* ... */
printAll(N,M,0);
/* ... */

knapsack3b.c
printAll() 8.2.1.: {7, 3, 2},
{8, 7}, {9, 6, 2} {9, 7, 3}. ,
. , .
- , F[i][j] = max(F[i1][j],F[i1][jmi]+ci), , . ,
F[][] , i-
F[i][.] F[i-1][.].
. F[] ( )
OldF[]. F[] i- F[i][.], OldF[]
(i1)- F[i-1][.].
unsigned calculate(void) /* */
{ unsigned F[MAXM], OldF[MAXM]; /* */
unsigned i,j,k;
for (j = 0; j <= M; j++)
OldF[j] = 0;
for (i = 1; i <= N; i++) {
for (j = 0; j <= M; j++)
if (j >= m[i] && OldF[j] < OldF[j-m[i]] + c[i])
F[j] = OldF[j-m[i]] + c[i];
else F[j] = OldF[j];
for (k = 0; k < M; k++)
OldF[k] = F[k];

8 -

492

}
return F[M];
}

knapsack3c.c

(N.) (N+).
. , F(k) k, ,
, ,
- k.
, , ,
, . , ,
,
.
- .
(N.M). knapsack3c.c,
.
(N.M).
(knapsack1.c). , , ,
F() - . (N), knapsack1.c, knapsack2a.c
knapsack2b.c, (N+) knapsack3a.c. , knapsack3b.c, (N++s), s
.
, . , ,
. : #i,
.
- . , #i , .
. , . ,
, ( ) , - . ,
.
, :
unsigned F[MAXM];
/* */
unsigned best[MAXM]; /* */
void calculate(void) /* */
{ unsigned i,j;
/* */
for (i = 0; i <= M; i++)
F[i] = 0;
/* */
for (j = 1; j <= N; j++)
for (i = 1; i <= M; i++)
if (i >= m[j])
if (F[i] < F[i-m[j]] + c[j]) {
F[i] = F[i-m[j]] + c[j];

8 -

493

best[i] = j;
}
}

knapsack4.c
1.
1 2, . . . . , 14:
: 14
:
7
7

,
, , . :
7 2. . 14
14 7.
, ,
(M.N), set[][] . best[]
.
. F[] best[]
:
void printSet(void)

/* , */
/* */
/* */
unsigned value = M;
printf("\n : ");
while (value) {
printf("%4u ", best[value]);
value -= m[best[value]];
}

knapsack4.c
, (N.M). (M).
(N+M), , ci mi .
( set[][]
best[]) -
.
best[] 0.
( 1), best[] .
char used(unsigned i, unsigned j)
{ /* j , F[i] */
while (i != 0 && best[i] != 0)
if (best[i] == j)
return 1;
else
i -= m[best[i]];
return 0;
}

8 -

494

void calculate() /* */
{ unsigned i,j;
/* */
for (i = 0; i <= M; i++)
best[i] = 0;
/* */
for (i = 1; i <= M; i++)
for (j = 1; j <= N; j++)
if (i >= m[j])
if (F[i] < F[i-m[j]] + c[j])
if (!used(i-m[j],j)) {
F[i] = F[i-m[j]] + c[j];
best[i] = j;
}
}

knapsack5.c
. - ,
M. - .
,
. , ,
. ,
,
M mi ( ci ). ,
,
,
. .
( 2.5.): ( )
.
. , , M, N, ci mi ,
.
, M mi . ,
. .
: ci = 1, mi = i M = N/2.
:
1. ,
.
2. , ( ).
3. set[] ? ?
4. , ?
, .
5. k .
?
6. ci = 1, mi = i M = N/2.

8 -

495

8.2.2.
:
n .
, ,
. . a b , . ab. , a b.
:
p , S .
a - () S, p/2,
b = p.
S? . S . mk k- . S m1.
S m2 m2+m1. S
. , S m3,
m1+m3, m2+m3 m1+m2+m3. S 3
. , k (k = 1, 2, ..., n) S s + mk ,
s S.
can[]. can[i]
1 0, i
. can[0] 1,
0. j k can[j] 1, 1 can[j+m[k]].
can[] - -.
. ,
can[] , k-
can[m[k]] 1. -, can[m[k]], 1
can[m[k]+m[k]] (
can[m[k]] 1),
can[m[k]+m[k]+m[k]] ( can[m[k]+m[k]] e 1) .. ,
1 (
) 1 .
, . -
.
- p/2 k can[], can[k] == 1.
, , , p/2, p.
#include <stdio.h>
#define MAX
100 /* */
#define MAXVALUE 200 /* */
unsigned char can[MAX*MAXVALUE]; /* ? */
const unsigned m[MAX] = {3,2,3,2,2,77,89,23,90,11}; /* */
const unsigned n = 10;
/* */
void solve(void)
{ unsigned long p; /* */
unsigned i, j;

8 -

496

/* p */
for (p = i = 0; i < n; p += m[i++])
;
/* */
for (i = 1; i <= p; i++)
can[i] = 0;
can[0] = 1;
/* */
for (i = 0; i < n; i++)
for (j = p; j+1 > 0; j--)
if (can[j])
can[j + m[i]] = 1;
/* - p/2 */
for (i = p / 2; i > 1; i--)
if (can[i]) {
printf("\n%s%u%s%lu", " :",i," :",p-i);
return;
}
}
int main(void)
{ solve();
return 0;
}

alanbob.c
, ,
(n.p). ,
c, n. p
c.n. (c.n2), . . (n2). , , can[], 8
8.2.1.
,
, . can[j] o can[],
can[j] 1. a ( ,
)
p. m[p] p a, , , . ..,
.
, can[],
,
.
curSum,
.
unsigned last[MAX*MAXVALUE]; /* ? */
void solve(void)
{ unsigned long p; /* */
unsigned long curSum = 0;

8 -

497

unsigned i, j;
/* p */
for (p = i = 0; i < n; p += m[i++])
;
/* */
for (last[0] = 0, i = 1; i <= p; i++)
last[i] = NOT_SET;
/* */
for (i = 0; i < n; i++) {
for (j = p; j+1 > 0; j--)
if (NOT_SET != last[j] && NOT_SET == last[j + m[i]])
last[j + m[i]] = i;
curSum += m[i];
}
/* - p/2 */
for (i = p / 2; i > 1; i--) {
if (NOT_SET != last[i]) {
printf("\n%s%u%s%lu", " :",i," :",p-i);
printf("\n :");
while (i > 0) {
printf(" %u", m[last[i]]);
i -= m[last[i]];
}
printf("\n .");
return;
}
}
}

alanbob2.c
:
: 136; : 166
: 11 90 23 2 2 3 2 3
.

:
1. ,
,
last[k].
2. , ?

8.2.3.
,
, , , .
n , :
M1M2...Mn

8 -

498

n+1 : r0, r1, ..., rn ,


Mi ri1ri ( ri1 ri ), i = 1, 2, ..., n.
A B pq qr
q

cij aik .bkj , i = 1, 2, ..., p; j = 1, 2, ..., r.


k 1

C pr.
p.q.r. ,
, , - .
( 7.6.).
B ( pq sr). , q A s B,
AB ( BA, r = p).
-,
.
, , . . A, B C, , : (AB)C = A(BC). , ,
. , 4 A, B, C D :
(A(B(CD)))
(A((BC)D))
((AB)(CD))
((A(BC))D)
(((AB)C)D)
, ,
.
: 1(1020), 2(2050), 3(501) 4(1100).
: 1(2(34)), :
1. L1 = 3 4
50.1.100
= 5000 [50100]
2. L2 = 2 L1
20.50.100 = 100000 [20100]
3. M = M1 L2
10.20.100 = 20000 [10100]
125000 . (1(23))4,
2200 :
1. L1 = 2 3
20.50.1
= 1000 [201]
2. L2 = 1 L1
10.20.1
= 200 [101]
3. M = L2 4
10.1.100
= 1000 [10100]
, , , , .
. ,
r0, r1,..., rn.
, , . , ,
. . - . , M1,
M2, ..., Mn, Mi, Mi+1, ..., Mj, 1 i j n. i = 1, j = n -

8 -

499

. , k (i k < j) , B = Mi, Mi+1, ..., Mk C = Mk+1,


Mk+2, ..., Mj, B C.
, B C
- . :
mij , MiMi+1...Mj, 1 i j n. (1 i j n):

mi , j

i j
0
j 1
min mi ,k mk 1, j ri 1 rk r j i j
k i

, mi,k mk+1,j k i j, mi,j. ,


.
#include <stdio.h>
#define MAX 100
#define INFINITY (unsigned long)(-1)
unsigned long m[MAX][MAX];

/* - */

/* */
const unsigned long r[MAX+1] = {12,13,35,3,34,2,21,10,21,6};
const unsigned n = 9;
/* */
/* */
unsigned long solveRecursive(unsigned i, unsigned j)
{ unsigned k;
if (i == j) return 0;
m[i][j] = INFINITY;
for (k = i; k <= j - 1; k++) {
unsigned long q = solveRecursive(i, k) +
solveRecursive(k + 1, j) +
r[i - 1] * r[k] * r[j];
if (q < m[i][j])
m[i][j] = q;
}
return m[i][j];
}
void printMatrix(void) /* */
{ unsigned i,j;
printf("\n :");
for (i = 1; i <= n; i++) {
printf("\n");
for (j = 1; j <= n; j++)
printf("%8lu", m[i][j]);
}
}
int main(void) {
printf("\n. : %lu",solveRecursive(1,n));
printMatrix();
return 0;
}

8 -

500

matrix1.c
,
.
Mi, Mi+1, ..., Mj, 1 i j n n(n+1)/2. , . , , memoization,
,
. , (n3).
long solveMemo(unsigned i, unsigned j)
{ unsigned k;
unsigned long q;
if (NOT_SOLVED != m[i][j]) /* */
return m[i][j];
if (i == j)
/* */
m[i][j] = 0;
else {
/* */
for (k = i; k <= j - 1; k++)
if ((q = solveMemo(i,k)+solveMemo(k+1,j)+r[i-1]*r[k]*r[j])
< m[i][j])
m[i][j] = q;
}
return m[i][j];
}
long solveMemoization(void)
{ unsigned i, j;
for (i = 1; i <= n; i++)
for (j = i; j <= n; j++)
m[i][j] = NOT_SOLVED;
return solveMemo(1, n);
}

matrix2.c
- , (mij)
. , , , . , . .
,
i j.
(
) -: , , ,
k, . k. -
. , - , 8.2.3.
m1,1 = 0

m1,2 = 10000

m1,3 = 1200

m1,4 = 2200

k2,1 = 1

m2,2 = 0

m2,3 = 1000

m2,4 = 3000

k3,1 = 1

k3,2 = 2

m3,3 = 0

m3,4 = 5000

k4,1 = 3

k4,2 = 3

k4,3 = 3

m4,4 = 0

8.2.3. , .

8 -

501

- i j, i = 1 j = n.
, m1,n, .
, (
solve()). printMatrix() m[][] .
.
, , ,
( getOrder()).
( buildOrder()
printMultiplyPlan()).
-, -
- , j, i+j, . . j
, , 1.
- (1 i i+j n):

mi , j

0
i j 1
min mi ,k mk 1, j ri 1 rk ri j
k i

j0
j0

j = 1.
. , j 2. (
) ,
. j 3 ..
.
#include <stdio.h>
#define MAX 100
#define INFINITY (unsigned long)(-1)
unsigned long m[MAX][MAX];

/* - */

struct {
unsigned left;
unsigned right;
} order[MAX * MAX];

/* */

unsigned long cnt;

/* */

/* */
const unsigned long r[MAX+1] = {12,13,35,3,34,2,21,10,21,6};
const unsigned n = 9;
/* */
/* , ,
* ,
* , */
void solve(void)
{ unsigned i, j, k;
/* */
for (i = 1; i <= n; i++)
m[i][i] = 0;
/* */
for (j = 1; j <= n; j++) {

8 -
for (i = 1; i <= n - j; i++) {
m[i][i + j] = INFINITY;
for (k = i; k < i + j; k++) {
unsigned long t = m[i][k]+m[k+1][i+j] + r[i-1]*r[k]*r[i+j];
/* */
if (t < m[i][i + j]) {
m[i][i + j] = t;
m[i + j][i] = k;
}
}
}
}
}
unsigned buildOrder(unsigned ll,unsigned rr) /* */
{ long ret = cnt++;
if (ll < rr) {
order[ret].left = buildOrder(ll, m[rr][ll]);
order[ret].right = buildOrder(m[rr][ll] + 1, rr);
}
else {
order[ret].left = ll;
order[ret].right = rr;
}
return ret;
}
void printMatrix(void) /* */
{ unsigned i, j;
printf("\n :");
for (i = 1; i <= n; i++) {
printf("\n");
for (j = 1; j <= n; j++)
printf("%8lu", m[i][j]);
}
}
void printMultiplyPlan(void) /* */
{ unsigned long i;
printf("\n :");
for (i = 0; i < cnt; i++)
if (order[i].left == order[i].right)
printf("\nL[%lu] = M%u", i, order[i].left);
else
printf("\nL[%lu]=L[%u]*L[%u]",i,order[i].left,order[i].right);
}
void getOrder(unsigned ll, unsigned rr) /* */
{ if (ll == rr) printf("M%u", ll);
else {
printf("(");
getOrder(ll, m[rr][ll]);
printf("*");
getOrder(m[rr][ll] + 1, rr);
printf(")");
}
}

502

8 -

503

int main(void) {
solve();
cnt = 0; buildOrder(1, n);
printf("\n : %lu", m[1][n]);
printMatrix();
printMultiplyPlan();
printf("\n : ");
getOrder(1, n);
return 0;
}

matrix3.c
:
: 2872
:
0
5460
1833
3057
1636
2140
2296
2980
2872
1
0
1365
2691
1324
1870
2004
2710
2572
1
2
0
3570
414
1884
1534
2724
1926
3
3
3
0
204
330
684
1170
1332
1
2
3
4
0
1428
1100
2268
1500
5
5
5
5
5
0
420
840
1092
5
5
5
5
5
6
0
4410
2520
5
5
5
5
5
7
7
0
1260
5
5
5
5
5
8
7
8
0
:
L[0] = L[1] * L[10]
L[1] = L[2] * L[3]
L[2] = M1
L[3] = L[4] * L[5]
L[4] = M2
L[5] = L[6] * L[7]
L[6] = M3
L[7] = L[8] * L[9]
L[8] = M4
L[9] = M5
L[10] = L[11] * L[16]
L[11] = L[12] * L[15]
L[12] = L[13] * L[14]
L[13] = M6
L[14] = M7
L[15] = M8
L[16] = M9
: ((M1*(M2*(M3*(M4*M5))))*(((M6*M7)*M8)*M9))

:
1. ,
, , .
2. , .
3. , , .. , n(n 1)/2 .
4. , n?
5. , ?

8 -

504

8.2.4. .
: , . 1 n .
, . , , . . ,

, - [Computer-5/98].
.
.
() n- (n2)
.

T ( n)

1 2n

n 1 n

, n . . n
k (k = 1, 2, ..., n1).
:

1
n 1
P ( n) P ( k ) P ( n k )

k 1

n 1

(1)

n2

P(n) = T(n1).
. - , :

6.

n+1
.
(n+2)- n n1 .
n . ( 1)
(2n)!/(n!n!) n+1.
ci, :
c0 = 1,
cn+1 = c0cn + c1cn1 + c2cn2 + ... + cnc0, n 0.
(2)
, :

7.

c0 = 1 (n+2)cn+1 = (4n+2)cn, n 0.
x

1.
2.
3.
4.
5.

1 1 4x
2x

(3)

(4)

8. n .
9. n .
10. , n n
.
11. , n+1
n+1 (
).

8 -

505

12. (0,0) (n,n) ,


x
, y = x, . ( 10)
13. (0,0) (n+1,n+1),
x ,
y = x, . ( 11)
14. , A B, n
, A , B.
15. , 2n , ,
, . ( 2)
,
( ). - . ,
n- n2 , n3 .
, 72 = 5 73 = 4
( 8.2.4.).
,
n .
8.2.4.. Ai 1 Ai Mi, i = 1, 2, ...,
6. , A0 A6 !
A4

A4

A3

A5

A3

A5
A2

A2

A6

A6

A0

A0

A1

A1

8.2.4a. .
A4

M4

M5
A5

A3
M3
A2

M6
A6
M2

A0

M1

A1

8.2.4. .
A0 A4 ( 8.2.4.). , 4
, . ,
: (M1M2M3M4)(M5M6). A1 A4 ,

8 -

506

(M1(M2M3M4))(M5M6),

A1 A3

(M1((M2M3)M4))(M5M6). (
8.2.4.).

A1

A5

A6

A4

A2

A3

8.2.4. (M1((M2M3)M4))(M5M6).
, n
, . . .
(n+1)-.
: .

.
L1 L2 (L1 , i- k, L2 (k+1)- j-) r[i-1].r[k].r[j], r[.]
. ,
: i1, k j. ,

, . ,

,
.
R . R, (P+2R), P . , P . ,
, r[i-1].r[k].r[j]
d[i-1][k] + d[k][j] + d[i-1][j], 1 i k < j n,

d[n1][n2] ( ) n1 n2. , ,
. , ,
: , .
M
F = P + 2R. R, P: R = (FP)/2.
(1 i j n):

i j
0
mi , j j 1
min mi ,k mk 1, j d i 1,k d k , j d i 1, j i j
k i

(5)

8 -

507

- - ,
j, i+j, . . j ,
, 1. , (1 i i+j n):

mi , j

0
i j 1
min mi ,k mk 1, j d i 1,k d k ,i j d i 1,i j
k i

j0

(6)

j0

- n- (
) n1 : , , . , n1.
solve().
. calcDist() d[][]. , m[1][n], R = (m[1][n]P)/2,
P . printResult().
k,
. :
writeCut().
#include <stdio.h>
#include <math.h>
#define MAX 80
#define INFINITY 1e20
double d[MAX][MAX];
double m[MAX][MAX];

/* */
/* - */

const struct {
/* */
int x;
int y;
} coord[MAX] = {{1,1},{5,-2},{10,1},{7,7},{1,7}};
const unsigned n = 5; /* */
/* */
void calcDist(void)
{ unsigned i, j;
for (i = 0; i < n - 1; i++)
for (j = i + 1; j < n; j++)
d[i][j] = sqrt(
(coord[i].x - coord[j].x) * (coord[i].x - coord[j].x) +
(coord[i].y - coord[j].y) * (coord[i].y - coord[j].y));
}
/* ,
* , */
void solve(void)
{ unsigned i, j, k;
for (i = 1; i < n; i++)
m[i][i] = 0; /* */
for (j = 1; j < n; j++) {
/* */
for (i = 1; i < n - j; i++) {
m[i][i + j] = INFINITY;
for (k = i; k < i + j; k++) {
double t = m[i][k] +
m[k+1][i+j] +
d[i-1][k] +

8 -
d[k][i+j] +
d[i-1][i+j];
if (t < m[i][i+j]) {
m[i][i+j] = t;
m[i+j][i] = k;
}

508

/* */

}
}
}
}
/* */
void printResult(void)
{ unsigned i;
double p = d[0][n-1]; /* */
for (i = 0; i < n; i++)
p += d[i][i+1];
printf("\n . %.2lf", (m[1][n-1] - p)/2);
}
/* */
void writeCut(unsigned ll, unsigned rr)
{ if (ll != rr) {
writeCut(ll, (unsigned) m[rr][ll]);
writeCut((unsigned) m[rr][ll] + 1, rr);
if (ll != 1 || rr != n-1)
printf("(%u,%u) ", ll, rr + 1);
}
}
int main(void) {
calcDist();
solve();
printResult();
printf("\n : ");
writeCut(1, n-1);
return 0;
}

catalan.c
:
17.49
: (1,3) (1,4)

:
1. ?
2. (1), (2) (3).
3. .
4. 8.2.4. A0 A6 ?

8.2.5.
, . - 8.2.4.
n
, (n+1)- n .
n .

8 -

509

,
2.3.
. ,
, , , . ,
,
.
( 2.4.),
. , -
45%
[-1980]. , ,
B- ( 2.4.2.),
, . B , , .
- ( 2.5.),
.
, ,
. ,
- log2 n . ,
n - n . .
(. .
-, - )
a1, a2, ..., an : a
.
n 1
2

a1, a2, ..., a


, a
,a
, ..., an.
n 1
n 1
n 1
2 1

2 1

2 2

,
. ,
.
, , ,
. ,
- . , , for
if - main goto [Sedgewick-1992].
, , - , -.
.
,
, .
.
, , d1 < d2 < ... < dn f1, f2, ..., fn , . . , . (, , . .
,
. , <.)
,
fi. 8.2.5.
. i, fi.

8 -

510

. : 1.4 = 4 (
f5 4). 1 3.2 = 6,
3 , f1 e 2. ,
4 3.3 = 9, 3 , f4 = 3.
, ( 8.2.5.):
2.3 + 7.2 + 1.4 + 3.3 + 4.1 + 6.2 + 5.3 = 64
5
4
2
7
1
2

6
6
4
3

7
5

3
1
2

8.2.5. .
, ,
( 8.2.3.). -
, di < di+1 < ... <
di+j. k (1 i k i+j n)
dk , , di < di+1 < ... < dk1
dk+1 < dk+2 < ... < di+j (1 j n1, 1 i nj).
s, s
di < di+1 < ... < di+j. ,
,
, . s.
, ,
, , s,
.
, , . . , . .
,
.
: - 8.2.5, , ( 0 2). . , m[i][i-1] 0, 1 i n+1. ,
m[][], , [Sedgewick-1992].
, k, . (n3) (n2). ,
- ,
- t t [-1996]. (
. ,
, ,
-. , ,

8 -

511

- ,
.)
? ,
. : 1) k 1; 2)
. getOrder().
, 90. h,
, ,
. getOrder(1,n,0).
. 8.2.5.
#include <stdio.h>
#define MAX 100
#define INFINITY (unsigned long)(-1)
unsigned long m[MAX][MAX];

/* - */

const unsigned long f[MAX+1] = {2,7,1,3,4,6,5}; /* */


const unsigned n = 7;

/* */

/* */
void solve(void)
{ unsigned i, j, k;
unsigned long t;
/* */
for (i = 1; i <= n; i++) {
m[i][i] = f[i-1];
m[i][i-1] = 0;
}
m[n+1][n] = 0;
/* */
for (j = 1; j <= n - 1; j++) {
for (i = 1; i <= n - j; i++) {
m[i][i + j] = INFINITY;
for (k = i; k <= i + j; k++) {
/* */
if ((t = m[i][k - 1] + m[k + 1][i + j]) < m[i][i + j]) {
m[i][i + j] = t;
m[i + j + 1][i] = k;
}
}
for (k = i-1; k < i + j; k++)
m[i][i+j] += f[k];
}
}
}
/* */
void PrintMatrix(void)
{ unsigned i,j;

8 -

512

printf("\n :");
for (i = 1; i <= n+1; i++) {
printf("\n");
for (j = 1; j <= n; j++)
printf("%8lu", m[i][j]);
}
}
/* */
void getOrder(unsigned ll, unsigned rr, unsigned h)
{ unsigned i;
if (ll > rr)
return;
if (ll == rr) {
for (i = 0; i < h; i++)
printf("
");
printf("d%u\n", rr);
}
else {
getOrder(ll, m[rr + 1][ll] - 1, h + 1);
for (i = 0; i < h; i++)
printf("
");
printf("d%lu\n", m[rr + 1][ll]);
getOrder(m[rr + 1][ll] + 1, rr, h + 1);
}
}
int main(void) {
solve();
printf("\n : %lu",
m[1][n]);
PrintMatrix();
printf("\n :\n"); getOrder(1,n,0);
return 0;
}

tree.c
8.2.5, . . . (
, .)
:
: 64
:
2
11
13
20
32
49
64
0
7
9
16
28
43
58
2
0
1
5
13
25
37
2
2
0
3
10
22
33
2
2
4
0
4
14
24
2
2
4
5
0
6
16
5
5
5
5
6
0
5
5
5
6
6
6
6
0
:
d1
d2
d3
d4

8 -

513

d5
d6
d7

:
1. ,
:
)
)
)
2.
8.2.5.?
3. .
4. (
8.2.3.), ( 8.2.4.)
.

8.2.6. -
. X = (x1, x2, ..., xm) Y = (y1, y2, ..., yn). -
Z = (z1, z2, ..., zk ), X Y . ,
Z X, Z
X. .
-.
8.2. , Z = (z1, z2, ..., zk ) X = (x1, x2, ...,
xm), i1 < i2 < ... < ik , xi j = zj, j = 1, 2, ..., k, 1 i1 < ik
n.
( ): X = aaaabbca Y = baadcaba. , aaa, abca ba
X, dca, bad aaa Y. a, aa ab X
Y, , 4, aaaa.
, - , aaaba,
.
, : X
Y,
X 2|X| ( 2m). F(i,j)
- Xi = (x1, x2, ..., xi) Yj = (y1, y2, ..., yj), 1 i m, 1 j n.
, xi = yj, F(i,j) = F(i1,j1) + 1. ,
- Zij Xi Yj xi ( yj,
). , xi yj, , Zij xi yj.
Zij xi, Zij - Xi1 = (x1, x2, ..., xi1) Yj, . . Zij
= Zi1,j. : F(i,j) = F(i1,j). Zij yj,
Zij - Xi Yj1 = (y1, y2, ..., yj1), . . Zij = Zi,j1 F(i,j) =
F(i,j1). Zij xi, yj, , Zij -
Xi-1 Yj1, . . Zij = Zi1,j1, F(i,j) = max(F(i1,j),F(i,j1)). ,
, - .
:

8 -

514

0
i 0 j 0

F i, j F (i 1, j 1) 1
i 0, j 0, xi y j
max F (i 1, j ), F (i, j 1) i 0, j 0, x y
i
j

, ,
. - ,
. m*n.
.
#include <stdio.h>
#include <string.h>
#define MAXN 100
#define MAX(a,b) (((a)>(b)) ? (a) : (b)) /* - */
char F[MAXN][MAXN];

/* */

const char x[MAXN] = "acbcacbcaba";


const char y[MAXN] = "abacacacababa";

/* */
/* */

/* - */
unsigned LCS_Length(void)
{ unsigned i, j, m, n;
m = strlen(x); /* */
n = strlen(y); /* */
/* */
for (i = 1; i <= m; i++)
F[i][0] = 0;
for (j = 0; j <= n; j++)
F[0][j] = 0;
/* */
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
if (x[i - 1] == y[j - 1])
F[i][j] = F[i - 1][j - 1] + 1;
else
F[i][j] = MAX(F[i - 1][j], F[i][j - 1]);
return F[m][n];
}
int main(void) {
printf("\n - : %u", LCS_Length());
return 0;
}

lcs1.c
, (mn). : ,
. .
-, ,
( ), :
1) xi = yj, , Zij xi, . .
F[i][j] = F[i-1][j-1] + 1;
2) xi yj, F[i-1][j] F[i][j-1],
F[i][j] = F[i-1][j], , xi Zij

8 -

515

xi yj, F[i-1][j] F[i][j-1],


F[i][j] = F[i][j-1], , yj Zij
: UPLEFT, UP LEFT, 1), 2) 3) . b[i][j]
( LCS_Length() -). -
. printLCS()
, .
, (
). printLCS2() .
- , b[][]
F[][] (
printLCS3()).
3)

#include <stdio.h>
#include <string.h>
#define MAX
100
#define LEFT
1
#define UP
2
#define UPLEFT 3
char F[MAX][MAX];
char b[MAX][MAX];
const char x[MAX] = "acbcacbcaba";
const char y[MAX] = "abacacacababa";

/*
/*
/*
/*

*/
*/
*/
*/

/* - */
unsigned LCS_Length(void)
{ unsigned i, j, m, n;
m = strlen(x); /* */
n = strlen(y); /* */
/* */
for (i = 1; i <= m; i++)
F[i][0] = 0;
for (j = 0; j <= n; j++)
F[0][j] = 0;
/* */
for (i = 1; i <= m; i++) {
for (j = 1; j <= n; j++) {
if (x[i - 1] == y[j - 1]) {
F[i][j] = F[i - 1][j - 1] + 1;
b[i][j] = UPLEFT;
}
else if (F[i - 1][j] >= F[i][j - 1]) {
F[i][j] = F[i - 1][j];
b[i][j] = UP;
}
else {
F[i][j] = F[i][j - 1];
b[i][j] = LEFT;
}
}
}
return F[m][n];
}
/* () */
void printLCS(void)
{ unsigned i = strlen(x),

8 -

while (i
switch
case
case
case
}

516

j = strlen(y);
> 0 && j > 0)
(b[i][j]) {
UPLEFT: printf("%c", x[i - 1]); i--; j--; break;
UP:
i--; break;
LEFT:
j--;

}
/* */
void printLCS2(unsigned i, unsigned j)
{
if (0 == i || 0 == j)
return;
if (UPLEFT == b[i][j]) {
printLCS2(i - 1, j - 1);
printf("%c", x[i - 1]);
}
else if (UP == b[i][j])
printLCS2(i - 1, j);
else
printLCS2(i, j - 1);
}
/* */
void printLCS3(unsigned i, unsigned j)
{ if (0 == i || 0 == j)
return;
if (x[i - 1] == y[j - 1]) {
printLCS3(i - 1, j - 1);
printf("%c", x[i - 1]);
}
else if (F[i][j] == F[i - 1][j])
printLCS3(i - 1, j);
else
printLCS3(i, j - 1);
}
int main(void) {
printf("\n
printf("\nPrintLCS:
printLCS();
printf("\nPrintLCS2:
printLCS2(strlen(x),
printf("\nPrintLCS3:
printLCS3(strlen(x),
return 0;
}

- : %u", LCS_Length());
( ): ");
: ");
strlen(y));
: ");
strlen(y));

lcs2.c
:

printLCS:
printLCS2:
printLCS3:

- : 9
( ): ababcacca
: accacbaba
: accacbaba

: (nm),
. , -

8 -

517

, ,
2.min(m,n) + (1) min(m,n) + (1), ,

[Cormen,Leiserson,Rivest1997]. (
8.2.1.).
:
1. .
2. , :
) 2.min(m,n) + (1)
) min(m,n) + (1)

8.2.7. -
, . X = (x1, x2, ..., xn). - X.
8.3. X = (x1, x2, ..., xn) ,
- ( ,
), . . x1 x2 ... xn.
. , . LNS(k) ( . Longest Non-decreasing
Subsequence) - Xk = (x1, x2, ..., xk ),
k X. . LNS(1) .
, LNS(k) LNS(k+1). ,

. (10, 40, 20, 30). 30
LNS(3), (10, 20).
(10, 40) . : ,
, ,
, , - .
: (1, 2, 5, 3, 4). , - , , , LNS(k+1). , ( 3)
- , ,
-. . . , - LNS(k). , (1, 2, 3, 4),
. (1, 5, 6, 2, 3, 4), , - , 2 - LNS(k).
, , , - . LNS(k) : LNS(k,s), - s,
Xk = (x1, x2, ..., xk ), 1 s k n.
LNS(k,s) . X . xk k, 1 k n. xk , , , ..., s- .
LNS(k, s1) xk LNS(k, s) s, 1 s k n.
- s s- xk . , xk
- - - , .
- - ,
, .

8 -

518

. :
/* */
for (k = 0; k <= n; k++) {
for (s = 1; s <= n; s++)
LNS[k][s] = +;
LNS[k][0] = -;
}
/* */
for (k = 1; k <= n; k++)
for (s = 1; s <= n; s++)
if (LNS[k-1][s-1] x[k] LNS[k-1][s])
LNS[k][s] = x[k];
else
LNS[k][s] = LNS[k-1][s];

- . s, LNS(k,s). r,
LNS_Length() .

X. LNS_Print() . LNS_Print2()
, .
#include <stdio.h>
#define MAX 100
const int x[MAX] = {100, 10, 15, 5, 25, 22, 12, 22}; /* */
/* x[] ! */
const unsigned n = 7; /* */
int LNS[MAX][MAX];

/* */

/* - */
unsigned LNS_Length(void)
{ unsigned i, j, r;
/* */
for (i = 0; i <= n; i++) {
for (j = 1; j <= n; j++)
LNS[i][j] = MAX + 1;
LNS[i][0] = -1;
}
/* */
r = 1;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (LNS[i - 1][j - 1] <= x[i] && x[i] <= LNS[i - 1][j]
&& LNS[i - 1][j - 1] <= LNS[i - 1][j]) {
LNS[i][j] = x[i];
if (r < j)
r = j;
}
else
LNS[i][j] = LNS[i - 1][j];

8 -

519

}
}
return r;
}
/* - ( ) */
void LNS_Print(unsigned j)
{ unsigned i = n;
do {
if (LNS[i][j] == LNS[i - 1][j])
i--;
else {
printf("%d ", x[i]);
j--;
}
} while (i > 0);
}
/* - */
void LNS_Print2(unsigned i, unsigned j)
{ if (0 == i) return;
if (LNS[i][j] == LNS[i - 1][j])
LNS_Print2(i - 1, j);
else {
LNS_Print2(i, j - 1);
printf("%d ", x[i]);
}
}
int main(void) {
unsigned len = LNS_Length();
printf("\n - : %u", len);
printf("\n (): "); LNS_Print(len);
printf("\n: "); LNS_Print2(n, len);
return 0;
}

lns1.c
:
- : 4
(): 22 22 15 10
: 10 15 22 22

, (n2) , . . .
: -,

, . (n)
(n2).
- . xi.
xi.
xj, (i < j n). xi - xj,
xj.
xj e l, , xi, l + 1.
, xi, xj,
l . xj, . . xi

8 -

520

- ,
, xi. LNS(i)
xi. LNS(i)
:
n

( LNS ( j )) j : x j xi ,1 i j n
1 j max
i 1, x j xi
LNS (i)
1

-
( LNS_Length()).
, next[],
xi xi. ,
, ( LNS_Print()).

#include <stdio.h>
#define MAX 100
const int x[MAX] = {100, 10, 15, 5, 25, 22, 12, 22}; /* */
/* x[] ! */
const unsigned n = 7; /* */
unsigned LNS[MAX];
unsigned next[MAX];

/* x[i] */
/* */

/* - */
unsigned LNS_Length(unsigned *start)
{ unsigned i, j;
unsigned l; /* xi,
/* l xj: */
/*
1) i < j <= n */
/*
2) xi <= xj
*/
unsigned len = 0; /* ( ) */
for (i = n; i >= 1; i--) {
for (l = 0, j = i + 1; j <= n; j++)
if (x[j] >= x[i] && LNS[j] > l) {
l = LNS[j];
next[i] = j;
}
LNS[i] = l + 1;
if (LNS[i] > len) {
len = LNS[i];
*start = i;
}
}
return len;
}
/* - */
void LNS_Print(unsigned start)
{ for (; LNS[start] >= 1; start = next[start])
printf(" %d", x[start]);
}
int main(void) {
unsigned start;

8 -

521

printf(" - : %u\n",
LNS_Length(&start));
printf(": "); LNS_Print(start);
return 0;
}

lns2.c
? (n) (n2). .
(n.log2 n).
LNS(k) xi X, k . 1 k i n k1
, . . Xi1 = {x1, x2, ..., xi1}
k1, - xi. ,
LNS(.) . k , . . ,
LNS(k). xi.
1. xi < LNS(1). : LNS(1) = xi.
2. xi LNS(k). : LNS(k+1) = xi.
3. LNS(1) xi < LNS(k). j (1 < j k), LNS(j1) xi < LNS(j),
LNS(j) = xi.
(1), (n). (log2 n).
xi X , (n.log2 n) (n) [-1995]. .
unsigned LNS_Length(void)
{ unsigned i, r, k, l, med;
for (LNS[1] = x[1], k = 1, i =
if (x[i] < LNS[1])
/*
LNS[1] = x[i];
else if (x[i] >= LNS[k]) /*
LNS[++k] = x[i];
else {
/*
l = 1;
r = k;
/*
while (l < r - 1) {
med = (l + r) / 2;
if (LNS[med] <= x[i])
l = med;
else
r = med;
}
LNS[r] = x[i];
}
}
return k;
}

lns3.c

2; i <= n; i++) {
1 */
2 */
3 */
*/

8 -

522

:
1. ,
. ,
(n).
2. . ?
3. . - ? ?

8.2.8.
s1 s2. s1 s2,
, :
replace(i,x)
i- (1 i |s1|) s1 x
insert(i,x)
x i s1
delete(i)
i- s1
, .
( )
s1 s 2 ( ).
.
- ( 8.2.6.).
-. .
, . s1
s2. .
.
.
F(i,j), () s1[1], s1[2], ..., s1[i] s2[1], s2[2], ..., s2[j]. cr s1
s2, ci e , cd .
F(i,j) ? :
1. s1[i] = s2[j]. F(i,j) = F(i 1,j1).
2. s1[i] s2[j]. :
F(i,j) = F(i1,j1) + cr. : .
F(i,j) = F(i,j1) + ci. s2 , s1.
F(i,j) = F(i1,j) + cd. s2 , .
: COST_DELETE == 1
(cd), COST_INSERT == 2 (ci) COST_REPLACE (COST_REPLACE == 0 (cr),
, COST_REPLACE == 3 ). , ,
1). F(i,j) F(i1,j1) + cr,
F(i,j1) + ci F(i 1,j) + cd.
. F(i,0) ,
i , .
, i s1.
F(i,0) = i.cd. , F(0,j) , .
j s2, j.ci.
editDistance().
, (nm), n s1, m
s2.

8 -

523

F[][] (n+m).
: INSERT, DELETE REPLACE. , INSERT DELETE s1.
s1,
, , , ,
s1. -.
#include <stdio.h>
#include <string.h>
#define
#define
#define
#define

MAX
COST_DELETE
COST_INSERT
COST_REPLACE(i, j)

100
1
2
((s1[i] == s2[j]) ? 0 : 3)

#define min2(a, b) (((a) < (b)) ? (a) : (b))


/* M. 2 */
#define min(a, b, c)
min2(min2(a,b), (c)) /* M. 3 */
unsigned F[MAX+1][MAX+1];
unsigned n1;
unsigned n2;

/* */
/* */
/* */

const char *s1="_abracadabra";


const char *s2="_mabragabra";

/* 1 ( ) */
/* - ( ) */

/* */
unsigned editDistance(void)
{ unsigned i, j;
/* */
for (i = 0; i <= n1; i++)
F[i][0] = i * COST_DELETE;
for (j = 0; j <= n2; j++)
F[0][j] = j * COST_INSERT;
/* */
for (i = 1; i <= n1; i++)
for (j = 1; j <= n2; j++)
F[i][j] = min(F[i - 1][j - 1] + COST_REPLACE(i, j),
F[i][j - 1] + COST_INSERT,
F[i - 1][j] + COST_DELETE);
return F[n1][n2];
}
/* */
void printEditOperations(unsigned i, unsigned j)
{
if (0 == j)
for (j = 1; j <= i; j++)
printf("DELETE(%u) ", j);
else if (0 == i)
for (i = 1; i <= j; i++)
printf("INSERT(%u,%c) ", i, s2[i]);
else if (i > 0 && j > 0) {
if (F[i][j] == F[i - 1][j - 1] + COST_REPLACE(i, j)) {
printEditOperations(i - 1, j - 1);
if (COST_REPLACE(i, j) > 0)
printf("REPLACE(%u,%c) ", i, s2[j]);

8 -

524

}
else if (F[i][j] == F[i][j - 1] + COST_INSERT) {
printEditOperations(i, j - 1);
printf("INSERT(%u,%c) ", i, s2[j]);
}
else if (F[i][j] == F[i - 1][j] + COST_DELETE) {
printEditOperations(i - 1, j);
printf("DELETE(%u) ", i);
}
}
}
int main(void) {
n1 = strlen(s1) - 1;
n2 = strlen(s2) - 1;
printf("\n : %u\n",
editDistance());
printEditOperations(n1, n2);
return 0;
}

transform.c
:
: 7
INSERT(1,m) DELETE(4) DELETE(5) REPLACE(7,g)

,
(nm) (m). ,
-, - ,
. .
,
, .
, , (mn)
(m). (min(n,m)),
, .
.
, , ,
, .
F(n,m) n/2
x F(n,m). ,
F(1,1) F(n/2,x) F(n/2,x) F(n/2,m).
. (nm). [Skiena1997]
- ,
-. - . (. . ),
. ,
- , . . - "" .

. , , -
, ,
, - . , - . -

8 -

525

. (. .
),
. [Skiena-1997]
.
smart . , , 8.2.8. (
):

ADVANCE
DELETE
REPLACE
INSERT
KILL

.

.
,
.
, .
.
, ,
.
.
8.2.8. smart .


, ,
- ( smart ) - . - .
, ,
(
).
.
, -,
F(i,0) = 0, F(i,0) = cd,
. REPLACE -
DELETE INSERT, , REPLACE
. , -
( 8.2.6.).
:
1.
(nm) (min(m,n)).
2. .
3. , , , ,
, .
4. , smart
.
5. ,
- ( 8.2.6.).

8 -

526

8.2.9.
. , n , si (1 i n). k .
.
, ,
.
.
,
, .
,
s1, s2, ..., sn.
k ,
, , .
:

1
k

s
i 1

, ,

. ,
, .
. : s1, s2, ..., sn i (1 i n): s1, s2, ..., si si+1, si+2, ..., sn. , k1 . k2
. :
j (1 j i). (sj+1, sj+2, ..., si) ,
(s1, s2, ..., sj) k3 . , , -
. .
. F(n,k), n k . . :
i
i

F i, j min max F l , j 1, s r , 1 i n, 1 j k
l 1
r l 1

, l + 1 i , . ,
:
F(1,j) = s1, 1 j k ( )
F(i,1) = s1 + s2 + ... + si, 1 i n ( )

.
, a .
, F(i,j)
i (1 i n) j (1 j k). nk.

(i,j) , -
. - ,
sl+1 + sl+2 + ... + si.

8 -

527

, (n).
, si,
. (1).
, ,
(n). (kn2).
F(i,j) F[][].
b[][], , .
. .
#include <stdio.h>
#define MAXN 80
#define INFINITY (unsigned long)(-1)
#define MAX(a,b) (((a)>(b)) ? (a) : (b)) /* - */
unsigned long p[MAXN];
/* */
unsigned long F[MAXN][MAXN]; /* */
unsigned long b[MAXN][MAXN]; /* */
/* ( ) */
const unsigned s[MAXN] = {0,23,15,89,170,25,1,86,80,2,27};
const unsigned n = 10; /* */
const unsigned k = 4;
/* */
/* k */
long doPartition(unsigned k)
{ unsigned i, j, l, m;
/* */
for (p[0] = 0, i = 1; i <= n; i++)
p[i] = p[i - 1] + s[i];
/* */
for (i = 1; i <= n; i++)
F[i][1] = p[i];
for (j = 1; j <= k; j++)
F[1][j] = s[1];
/* */
for (i = 2; i <= n; i++)
for (j = 2; j <= k; j++)
for (F[i][j] = INFINITY, l = 1; l <= i - 1; l++)
if ((m = MAX(F[l][j - 1], p[i] - p[l])) < F[i][j]) {
F[i][j] = m;
b[i][j] = l;
}
return F[n][k];
}
void print(unsigned from, unsigned to)
{ unsigned i;
printf("\n");
for (i = from; i <= to; i++)
printf("%u ", s[i]);
}
void printPartition(unsigned n, unsigned k)
{ if (1 == k)

8 -

528

print(1, n);
else {
printPartition(b[n][k], k - 1);
print(b[n][k] + 1, n);
}
}
int main(void) {
printf("\n : %lu", doPartition(k));
printPartition(n, k);
return 0;
}

partitio.c
:
: 170
23 15 89
170
25 1 86
80 2 27

:
1. b[][] ?
2. .
3. , .

8.3.
(, . . ) , . , - .
. , , ( , ;
).
, - , . . .
, , . ,
- . -
, - .

8.3.1.
(
1.2.2.). :
unsigned long fib(unsigned n)

8 -

529

{ if (n < 2)
return n;
else
return fib(n-1) + fib(n-2);
}

fibrec.c
, , () . :

, memoization.
. n .
#include <stdio.h>
#include <string.h>
#define MAX 256
const unsigned n = 10; /* 10- */
unsigned long m[MAX + 1];
/* , */
unsigned long fibMemo(unsigned n)
{ if (n < 2)
m[n] = n;
else if (0 == m[n])
m[n] = fibMemo(n - 1) + fibMemo(n - 2);
return m[n];
}
int main(void) {
memset(m, 0, MAX * sizeof(*m));
printf("\n%u- : %lu", n, fibMemo(n));
return 0;
}

fibmemo.c
, F0 = 1. ,
- .
n- , . :
n

1 1 Fn Fn1
(1)


1 0 Fn1 Fn2
, n-
n- . ,
( 7.5, [-1998c])
(log2 n), , , n.
- , ,
,
.
, :

8 -

530

#include <assert.h>
#include <stdio.h>
#include <string.h>
#define SQR(X) ((X) * (X))
const unsigned n = 10;
unsigned long matrE[2][2] = { { 1, 1 }, { 1, 0 } }; /* */
unsigned long matr[2][2]; /* */
void fibMatr(unsigned n, unsigned long matr[][2])
{ static unsigned long lMatr[2][2]; /* */
static unsigned long sq12;
/* */
if (n < 2)
memcpy(matr, matrE, 4 * sizeof(matr[0][0]));
else if (0 == n % 2) {
fibMatr(n / 2, lMatr);
sq12 = SQR(lMatr[0][1]);
matr[0][0] = SQR(lMatr[0][0]) + sq12;
matr[1][1] = SQR(lMatr[1][1]) + sq12;
matr[0][1] = matr[0][0] - matr[1][1];
matr[1][0] = matr[0][1];
}
else {
fibMatr(n - 1, lMatr);
matr[1][1] = lMatr[0][1];
matr[0][1] = lMatr[0][0];
matr[0][0] = lMatr[0][0] + lMatr[1][0];
matr[1][0] = lMatr[0][1];
}
}
int main(void) {
fibMatr(n - 1, matr);
printf("\n%u- : %lu", n, matr[0][0]);
return 0;
}

fibmatr.c
, matr[][] 22. , , . : ,
/ , , , ,
a .
, - n- , :

Fn2 Fn2 , n 2k
1
Fn 2
2
Fn1 Fn2 , n 2k 1

(2)

8 -

531

, .
#include <stdio.h>
#include <string.h>
#define MAX 250
#define SQR(X) ((X)*(X))
unsigned long m[MAX+1];
const unsigned n = 10;
#include <stdio.h>
#include <string.h>
#define MAX 250
#define SQR(X) ((X)*(X))
unsigned long m[MAX+1];
const unsigned n = 10;
/* , */
unsigned long fMemo2(unsigned n)
{ if (n < 2)
m[n] = 1;
else if (0 == m[n])
if (1 == n % 2)
m[n] = fMemo2(n - 1) + fMemo2(n - 2);
else
m[n] = SQR(fMemo2(n / 2)) + SQR(fMemo2(n / 2 - 1));
return m[n];
}
int main(void) {
memset(m, 0, MAX * sizeof(m[0]));
printf("\n%u- : %lu", n, fMemo2(n - 1));
return 0;
}

fibmemo2.c
, , : - ?
. ,
n = 48
. - ,
double IEEE, ,
18-19. . .
1000- .
- n
: .
,
.
.
:
1. (1).

8 -

532

2. (2) .
3. , ,
(1). .
4. - .
5.
n- n: 10, 100, 200, 500,
1000.

8.3.2.
( 1.1.5), C nk n ,
k

- .
:

C nk

n!
, 0 k n, n k
k!n k !

1 , :

1
k 0 k n
n n 1 n 1


0 k n
k k 1 k
kn
0
:
unsigned long binom(unsigned n,unsigned k) /* . */
{ if (k > n) return 0;
else if (0 == k || k == n) return 1;
else return binom(n-1, k-1) + binom(n-1, k);
}

binom.c
n- : fibRec(). , : . , binom(6,4) binom(5,3) binom(5,4). binom(4,3),
. - -. , ,
C nk .

, . ,
.
, k-
(k1)- . - . ,
(n.k) (k).
#define MAX 200
unsigned long m[MAX];
unsigned long binomDynamic(unsigned n, unsigned k)
{ unsigned i, j;
for (i = 0; i <= n; i++) {

8 -

533

m[i] = 1;
if (i > 1) {
if (k < i - 1) j = k; else j = i - 1;
for (; j >= 1; j--) m[j] += m[j - 1];
}
}
return m[k];
}

binom2.c
:
1. , .
2. (n.k) ,
?

8.3.3.
: A B - 2n1 ,
p (0 p 1) q = 1p
. , n . . .
P(i,j) , i , j . , ,
, P(n,n), n . A 0
, . , P(0,j) = 1 (1 j n). , B 0 , A 0: P(i,0)
= 0 (1 i n). :
P(0,j) = 1, j = 1, 2, , n
P(i,0) = 0, i = 1, 2, , n
P(i,j) = p.P(i1, j) + q.P(i, j1) , i > 0 , j > 0
, P(0,0) . , , ( ,
.).
, n p P(n,n), . . . ,
, P(i,j). i = j = n
P(n,n):
/* */
float P(unsigned i, unsigned j)
{ if (0 == j)
return 0.0;
else if (0 == i)
return 1.0;
else
return p * P(i - 1, j) + (1 - p) * P(i, j - 1);
}

series.c
( 8.3.1.) ( 8.3.2.)
. ,
P(3,4) P(2,4) P(3,3),

8 -

534

P(2,3). P(2,3) . -
-. 1.4.9.,
, P(n,n) (4n).
- , P(i,j) i j ,

. . i i + j [Aho,Hopcroft,Ullman1987]. , - , ,

. , P(i,j) binom(i+j,j).

P(i,j) = p.P(i1, j) + q.P(i, j1)


:
binom(i+j,j) = binom(i+j 1, j) + binom(i+j1, j1).
p q, , .
, , P(n,n),
2n . , ,

n
(2n)! / (2.n!).
, . (,
, n = 14).
. : char calculated ( : ?) float value ( ).
-. , ,
.
pDynamic() calculated 0, pDyn(),
.
#define MAX 100
#define q (1 - (p))

/* B */

const float p = 0.5;


const unsigned n = 5;

/* A */

struct {
char calculated;
float value;
} PS[MAX][MAX];

/* ? */
/* */

float pDyn(unsigned i, unsigned j) /* */


{ if (!PS[i][j].calculated) {
PS[i][j].value = p * pDyn(i - 1, j) + q * pDyn(i, j - 1);
PS[i][j].calculated = 1;
}
return PS[i][j].value;
}
float pDynamic(unsigned i, unsigned j)
{ unsigned k, l;

8 -

535

for (k = 1; k <= i; k++)


for (l = 1; l <= j; l++)
PS[k][l].calculated = 0;
for (k = 1; k <= i; k++) {
PS[0][k].value = 1.0;
PS[0][k].calculated = 1;
}
for (k = 1; k <= j; k++) {
PS[k][0].value = 0.0;
PS[k][0].calculated = 1;
}
return pDyn(i, j);
}

series2.c
calculated. , ,
, .
, 1,
. ,
, . ,
( 0),
. (?).
#define MAX 100
#define NOT_CALCULATED (-1)
#define q (1 - (p))
const float p = 0.5;
const unsigned n = 5;
float PS[MAX][MAX];

/* B */
/* A */

float pDyn(unsigned i, unsigned j) /* */


{ if (PS[i][j] < 0)
PS[i][j] = p * pDyn(i - 1, j) + q * pDyn(i, j - 1);
return PS[i][j];
}
float pDynamic2(unsigned i, unsigned j)
{ unsigned k, l;
for (k = 1; k <= i; k++)
for (l = 1; l <= j; l++)
PS[k][l] = NOT_CALCULATED;
for (k = 1; k <= i; k++)
PS[k][0] = 0.0;
for (k = 1; k <= j; k++)
PS[0][k] = 1.0;
return pDyn(i, j);
}

series3.c
, (n2)
, . , , , memoization.
,
.
,
, , -

8 -

536

. .
8.3.3.
j\i
0
1
2
3
4

0
0
0
0

1
1
1/2
1/4
1/8
1/16

2
1
3/4
1/2
5/16
3/16

3
1
7/8
11/16
1/2
11/32

4
1
15/16
13/16
21/32
1/2

8.3.3. P(i,j) n = 4 p = 1/2 (0 i, j n).


,
8.3.3., , :
. ,
? -,
, . ,
( 8.3.3.).

8.3.3. .
,

. ( - ,
, .)
float pDynamic3(unsigned i, unsigned j)
{ float P[MAX][MAX];
unsigned s, k;
P[0][0] = 0.0; /* . */
for (s = 1; s <= i + j; s++) {
P[0][s] = 1.0;
P[s][0] = 0.0;
for (k = 1; k <= s - 1; k++)
P[k][s - k] = p * P[k - 1][s - k] + q * P[k][s - k - 1];
}
return P[i][j];
}

series4.c

(n2). , . (n2).
:
1. 0.0 - ? ?
2. , (n).

8 -

537

3. ( 1.1.5., 8.3.2.).
, ?

8.3.4.
: n : c0, c1, ..., cn1,
s. s
. c0, c1, ..., cn1 .
.
: , , . ,
.
- . F(s,m) ,
s , m.
:

0
s0
F ( s, s )
sm

F ( s , m) 1
F (s i, is) m & k : c s
i 1, 2 ,...,m ;k :ck i
k

F ( s i, i )

i 1, 2,...,m;k:ck i
. , 0
. , s - s. .
, ck s, m. ,
sck , , ck .
, , F(s ck , ck ). ,
F(sck , ck ) ck , ck s ck m, F(s,m).
, s.
count() F(s,m) , ,
. . memoization. s
count(s,s), F(s,s).
.
#include <stdio.h>
#define MAXCOINS 100 /* */
#define MAXSUM
100 /* */
unsigned long F[MAXSUM][MAXSUM];
/* */
unsigned char exist[MAXSUM]; /* */
const unsigned coins[MAXCOINS] = {1,2,3,4,6}; /* */
const unsigned sum = 6;
/* , */
const unsigned n = 5;
/* */
/* */
void init(void)
{ unsigned i, j;
/* */
for (i = 0; i <= sum; i++)
for (j = 0; j <= sum; j++)
F[i][j] = 0;
/* - */

8 -

538

for (i = 0; i <= sum; i++)


exist[i] = 0;
for (i = 0; i < n; i++)
exist[coins[i]] = 1;
}
/* sum */
unsigned long count(unsigned sum, unsigned max)
{ unsigned long i;
if (sum <= 0)
return 0;
if (F[sum][max] > 0)
return F[sum][max];
else {
if (sum < max)
max = sum;
if (sum == max && exist[sum]) /* */
F[sum][max] = 1;
for (i = max; i > 0; i--) /* */
if (exist[i])
F[sum][max] += count(sum - i, i);
}
return F[sum][max];
}
int main(void) {
init();
printf("\n %u %lu",
sum, count(sum, sum));
return 0;
}

coin_min.c
:
6 10

, 10 1, 2, 3, 4
6, :
6
6
6
6
6
6
6
6
6
6

=
=
=
=
=
=
=
=
=
=

6
4
4
3
3
3
2
2
2
1

+
+
+
+
+
+
+
+
+

2
1
3
2
1
2
2
1
1

+ 1
+
+
+
+
+
+

1
1
2
1
1
1

+ 1
+ 1
+ 1 + 1
+ 1 + 1 + 1

:
1. .
2. .

8 -

539

8.3.5.
, ,
, . . , . ,
S.
- . .
F(s,k), s
k : c0, c1, ..., ck1. :

0
F ( s, k )
1 F s c k , k 1 F ( s, j ), j max c c k

i
F s c k , k 1 F ( s, j ), j max c c k
i

s0
k 0

l : cl s

. ,
s. :
1) k- . .
2) k- .
.
, s.
#include <stdio.h>
#define MAXCOINS
#define MAXSUM
#define SWAP(a, b)

100 /* */
100 /* */
{ a = a ^ b; b = a ^ b; a = a ^ b; }

unsigned long F[MAXSUM][MAXSUM]; /* */


const unsigned n = 7;
/* */
const unsigned sum = 6; /* , */
unsigned coins[MAXCOINS] = {1,2,2,3,3,4,6}; /* */
/* */
void init(void)
{ unsigned i, j;
/* */
for (i = 0; i <= sum; i++)
for (j = 0; j <= sum; j++)
F[i][j] = 0;
}
/* */
void sort(void)
{ unsigned i, j;
for (i = 0; i < n - 1; i++)
for (j = i + 1; j < n; j++)
if (coins[i] > coins[j])
SWAP(coins[i], coins[j]);
}
/* sum k */
unsigned long count(int sum, int k)
{ unsigned j;
if (sum <= 0 || k < 0)

8 -

540

return 0;
if (F[sum][k] > 0)
return F[sum][k];
else {
if (coins[k] == (unsigned)sum)
F[sum][k] = 1;
F[sum][k] += count(sum - coins[k], k - 1);
j = k;
while (coins[j] == coins[k]) j--;
F[sum][k] += count(sum, j);
}
return F[sum][k];
}
int main(void) {
init();
sort();
printf("\n %u %lu.",
sum, count(sum, n - 1));
return 0;
}

coinmin2.c
:
6 4.

, 4 1,
2, 2, 3, 3, 4 6, ( ,
, ):
6
6
6
6

=
=
=
=

6
4 + 2
3 + 3
3 + 2 + 1

:
1. .
2. .
3. .

8.3.6.
8.4. n
, , n.
n = 4 :
4
3
2
2
1

1
2
1 1
1 1 1

. -
S(n,m) n , m.

8 -

541

S(n,n). S(n,m)
[,-1988]:

1
S (n, n)

S (n, m)
1 S (n, n 1)
S (n, m 1) S (n m, m)

n 1 m 1
nm
nm
nm

1) S(n,1) = 1 ( - 1.)
2) S(1,m) = 1 ( m.)
3) S(n,m) = S(n,n), n < m ( n - n
.)
4) S(n,n) = 1 + S(n,n1) ( n, n ,
S(n,n1).)
5) S(n,m) = S(n,m1) + S(nm,m), n > m ( n
, - m, e S(n,m1), S(nm,m).)
#include <stdio.h>
#define MAX 100
unsigned long M[MAX][MAX];
const unsigned n = 10;

/* */

/* n */
unsigned long getNum(unsigned n)
{ unsigned i, j;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (1 == j)
M[i][j] = 1;
else if (1 == i)
M[i][j] = 1;
else if (i < j)
M[i][j] = M[i][i];
else if (i == j)
M[i][j] = 1 + M[i][i - 1];
else
M[i][j] = M[i][j - 1] + M[i - j][j];
return M[n][n];
}
int main(void)
{ printf(" %u : %lu",
n, getNum(n));
return 0;
}

breaknum.c
:
1. .
2. .
3. ?

8 -

542

4. .

8.3.7.
[Timus, 1009],
.
: n- k- . , , .
n k (2 k 10; n 2; 4 n + k 18).
:
4308063 7 ( k 9)
1000198
0002323 7-, 4 ( k 4)
,
. :
, . , ,
q(n,k). n-
k- , , nk .
F(n,k) = nk q(n,k).
? . n1 -
. , n = 8 :
00??????
x00?????
_x00????
__x00???
___x00??
____x00?
_____x00

0 0, ? k- (0, 1, ..., k1), x


k- (1, 2, ..., k1), _
, _ .
, , ,
, , ,
. , .
x.
? : ___x00??. F(s,k) s- k- . F(3,k), (k1), k2.
: F(3,k).(k1).k2
. ,
, :
s 2

qs, k k s 2 F i 1, k .(k 1).k s i 2


i 1

(ks2) . ,
:
F(0,k) = 1
F(1,k) = k
F(2,k) = k(k1)

8 -

543

- :
F(s,k) = ks q(s,k)
, F(n,k) -, F(3,k) s 1
. - memoization. k .
#include <stdio.h>
#define MAX
100
#define NOT_SOLVED (unsigned long)(-1)
unsigned long F[MAX];
/* */
unsigned long pow[MAX]; /* k */
const unsigned n = 10;
const unsigned k = 7;
void init(void)
{ unsigned i;
for (i = pow[0] = 1; i <= n; i++) {
pow[i] = k * pow[i - 1];
F[i] = NOT_SOLVED;
}
}
unsigned long solve(unsigned s)
{ unsigned i;
if (NOT_SOLVED == F[s]) {
F[s] = pow[s - 2];
for (i = 1; i < s - 1; i++)
F[s] += solve(i - 1) * (k - 1) * pow[s - i - 2];
F[s] = pow[s] - F[s];
}
return F[s];
}
int main(void) {
init(); F[0] = 1; F[1] = k; F[2] = k * k - 1;
printf("%lu\n", (k - 1) * solve(n - 1));
return 0;
}

no2zero.c
:
1. - ?
2. .

8.3.8.
. ,
. (. . ) . (
) . ,
(
. ,

8 -

544

.). -
, .
, , , .
. ,
, , ,
. , ,
.
8.5. ( [1996]):
= <N, T, S, P>,
:
N , ;
T , , N T
, . . NT = ;
S ( ), SN;
P () , :
= A, A , ,(NT)* (,
, );
(NT)*;
d() d(), ( - ), . .
.
* (. . , ), +
, d() .
, L = {ac,ad,bc,bd}
:
= <{S,A,B}, {a,b,c,d}, S, {SAB,Aa,Ab,Bc,Bd}>
. -
:
8.5.;
;
- ().
- , IBM, . (
. , ,
, .)
- L :
S ::= AB
A ::= a|b
B ::= c|d

S, A B (- <_>.
. : <>,
<> .). S , a b , ::=, |, <, >
. (S ::= AB ),
, . ::=
. ::= , , . | , <
> , .

8 -

545

,
, .
- :
;
- .
, . , - . - P. -
,
.
- . ,
( , )
.
.
P (
) . ( .) . , , . -.
,
, [-1984], [1996], [-1987] [-1980].

, , : 0, 1, 2 3. i = 1, 2, 3
i i1,
. - , :
1) 0 ( )
2)

1A2, 1, 2(NT)*, (NT)+, AN


1 ( )
1A212, 1, 2(NT)*, (NT)+, AN

3)

1 2 .
2 ( )

4)

A, (NT)+, AN
3 ( )

AB, AaB, Aa, aT, A,BN


,
S ( ). [-1996]
, . : 1 2:
1)
2)

1: Aa, aT, AN
2: ABC, A,B,CN

, A, :

8 -

546

L(A) = {bc | bL(B), cL(C), BC} {a | Aa}


, = <N,T,S,P>, L(S). ,
( ) , , .
, ,
. t[R][1...n][1...n], RN. n x (string). i,j (1 i j n) t[R][i][j] == 1 ,
xi, xi+1, ..., xj , R. :
t[R][i][j] == 1, , :
1) i == j Rxi

2)

k (i k < j) RTU , t[][i][k] == 1


t[U][k+1][j] == 1

( [Parberry-1995]):
unsigned cfl(void) {
for ( R)
for (i = 1; i <= n; i++)
if (Rxi)
t[R][i][i] = 1;
/* 2 */
for (d = 1; d < n; d++)
for (i = 1; i <= n-d; i++) {
j = i + d;
for ( R) {
t[R][i][j] = 0;
for ( RTU)
t[R][i][j] = kj 1i (t[T][i][k]t[U][k+1][j])
}
}
return t[S][1][n]; /* S */
}

- - .
1 2 .
0. 1) 1, 2
2. ,
( 8.2.1.): i == j,
[i,j] .
.
#include <stdio.h>
#include <string.h>
#define MAX
30
#define LETTERS 26

/* */
/* */

const struct { /* , : S->a */


char S, a;
} prodT[MAX+1] = {
{0,0},
/* */
{'S','s'}, /* S->s */

8 -

547

{'A','a'}, /* A->a */
{'B','b'} /* B->b */
};
const unsigned cntT = 3;
/* 1: S->a */
const char string[MAX + 1] = "aaasbbb"; /* , */
const struct { /* , : S->AB */
char S, A, B;
} prodNT[MAX+1] = {
{0,0,0},
/* */
{'S','A','R'}, /* S->AR */
{'S','A','B'}, /* S->AB */
{'R','S','B'}, /* R->SB */
};
const unsigned cntNT = 3;
/* 2: S->AB */
unsigned char t[LETTERS][MAX][MAX]; /* */
/* */
unsigned cfl(void)
{ unsigned i, j, k, l, d, let, n;
/* */
n = strlen(string); /* */
/* "" */
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
for (let = 0; let < LETTERS; let++)
t[let][i][j] = 0;
/* 1 , */
for (i = 1; i <= cntT; i++)
for (j = 1; j <= n; j++)
if (prodT[i].a == string[j - 1])
t[prodT[i].S - 'A'][j][j] = 1;
/* 2 */
for (d = 1; d < n; d++)
for (i = 1; i <= n - d; i++)
/* S */
for (j = i + d, k = 1; k <= cntNT; k++)
for (l = i; l <= j - 1; l++)
if (t[prodNT[k].A - 'A'][i][l] && t[prodNT[k].B - 'A'][l+1][j])
t[prodNT[k].S - 'A'][i][j] = 1;
return t['S' - 'A'][1][n];
}
int main(void) {
printf("\n %s%s", cfl() ? "" : " ",
" !");
return 0;
}

cfl.c
:
!

:
1. .

8 -

548

2. aaasbbb -?
3.
. ?
4. . - .
5.
? ?
6. , - ?
7. ? XML? ?

8.3.9.
, , .
, .
,

, . :
0. p,q,r,s,t,u,v,w,x,y,z N,C,D,E,I.
1. p,q,r,s,t,u,v,w,x,y,z, ,
.
2. S , NS .
3. S T , CST, DST, EST IST.
4. , , 0,1,2 3.
, Isz NIsz , Cp Cqpq .
8.3.8. 1 . 2 : N (. .
NS), ,
S. 3 : T S, CST,
DST, EST IST . . .
F(i,j), , si, si+1,..., sj
.
, .
:
1. F(i,j) = 1, i = j sj{ p, q, r, s, t, u, v, w, x, y, z }
2. F(i,j) = 1, si = N F(i+1,j) = 1.
3. F(i,j) = 1, si{C,D,E,I} k, F(i+1,k) = 1 F(k+1,j) = 1
4. F(i,j) = 0
, - memoization.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
#define NOT_CALCULATED 2
unsigned char F[MAX][MAX]; /* */
const char *s = "NNNNNNNNECINNxqpCDNNNNNwNNNtNNNNs"; /* */
unsigned n; /* */
void init(void)
{ unsigned i, j;

8 -

549

n = strlen(s);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
F[i][j] = NOT_CALCULATED;
}
unsigned char check(unsigned st, unsigned en)
{ unsigned k;
if (NOT_CALCULATED != F[st][en])
return F[st][en];
else {
/* 2 */
if (st == en)
F[st][en] = (s[st] >= 'p' && s[st] <= 'z');
else if ('N' == s[st])
F[st][en] = check(st + 1, en);
else if('C' == s[st] || 'D' == s[st] || 'E' == s[st] || 'I' == s[st])
{
k = st + 1;
while (k < en && !(check(st + 1, k) && check(k + 1, en)))
k++;
F[st][en] = (k != en);
}
else
F[st][en] = 0;
return F[st][en];
}
}
int main(void) {
init();
printf("\n. %s", check(0,n-1) ? "!" : "!!!");
return 0;
}

hedonia.c
:
1. .
2. NNNNNNNNECINNxqpCDNNNNNwNNNtNNNNs,
? ?
3. ?
4. , :
) ;
) ;
) -

8.3.10.
a
b
c

a
b
c
a

b
b
b
c

c
a
a
c

8.3.10. A = {a, b, c}.

8 -

550

x = x1x2...xn A k .
, a, A. A ,
, .
a,bA abA. A = {a, b, c}.
A 8.3.10.
abc. (ab)c, (ab)c = bc =
a. , a(bc), a(bc) = aa = b.
. , A, A, - a, x (
- ).
can(i,j,c), , , , i- j- , c (1 i j n). :
1)
2)

can(i,i,c) == 1, , xi == c
can(i,j,c) == 1, , i < j c1 c2 ,
c1*c2 == c p (i p < j), can(i,p,c1) == 1
can(p+1,j,c2)== 1

xi i- x, * . , table[][][]. p, can() 1.
, ,
.
#include <stdio.h>
#include <string.h>
#define NOT_CALCULATED (unsigned char)(-1)
#define MAXSLEN 100 /* */
#define LETTS
3
/* */
/* */
char rel[LETTS][LETTS] = {
{ 'b', 'b', 'a' },
{ 'c', 'b', 'a' },
{ 'a', 'c', 'c' }};
char *s = "bacacbcabbbcacab";
unsigned char table[MAXSLEN][MAXSLEN][LETTS];
unsigned char split[MAXSLEN][MAXSLEN];
unsigned char can(unsigned char i, unsigned char j, unsigned char ch)
{ unsigned char c1, c2, pos;
if (table[i][j][ch] != NOT_CALCULATED)
return table[i][j][ch]; /* */
if (i == j)
return(s[i] == ch + 'a');
for (c1 = 0; c1 < LETTS; c1++)
for (c2 = 0; c2 < LETTS; c2++)
if (rel[c1][c2] == ch + 'a')
for (pos = i; pos <= j - 1; pos++)
if (can(i, pos, c1))
if (can(pos + 1, j, c2)) {

8 -

551

table[i][j][ch] = 1;
split[i][j] = pos;
return 1;
}
table[i][j][ch] = 0;
return 0;
}
void putBrackets(unsigned char i, unsigned char j)
{ /* */
if (i == j)
printf("%c", s[i]);
else {
printf("(");
putBrackets(i, split[i][j]);
printf("*");
putBrackets(split[i][j] + 1, j);
printf(")");
}
}
int main(void) {
unsigned char len = strlen(s);
memset(table, NOT_CALCULATED, sizeof(table));
if (can(0, len - 1, 0))
putBrackets(0, len - 1);
else
printf(" ");
return 0;
}

relation.c
:
(((b*a)*(c*a))*(((c*(b*c))*a)*((b*((b*b)*(c*a)))*(c*(a*b)))))

:
1. .
2. .
3. .

8.4.
- ,
,
.
- .
- ,
- ,
.

8 -

552

8.4.1.
: " " ,
. " " 1, 2, ..., 10 . ci (i = 1, 2, ..., 10), :
c1 = 12
c2 = 21
c3 = 31
c4 = 40
c5 = 49
c6 = 58
c7 = 69
c8 = 79
c9 = 90
c10 = 101

n (1 n 100) .
, -, ?
: , 10
. - , k
.
.
F(i), i . cj j . F(i) .
F(0) = 0.
F(i) = min[F(ij) + cj], 1 i n, 1 j min(i,k)
F(i) , 1.
i (1 i n) F(i), j
, . , F(i)
F . j ,
, i
.
(n).
j1, F(n). j2, F(nj1) . . . , .
, . , , , .
.
- F, , dist[]. solve()
for- (n) (k), , . . (1). (n.k).
#include <stdio.h>
#define MAXN
100
/* */
#define MAXK
20
/* */
#define INFINITY (unsigned)(-1)
struct {
unsigned last;
unsigned value;

/* */
/* */

8 -

553

} dist[MAXN];
const unsigned values[MAXK+1] = {0,12,21,31,40,49,58,69,79,90,101};
const unsigned n = 15;
const unsigned k = 10;
void solve(unsigned n) /* */
{ unsigned i, j;
dist[0].value = 0;
for (i = 1; i <= n; i++) {
dist[i].value = INFINITY;
for (j = 1; j <= k && j <= i; j++)
if (dist[i - j].value + values[j] < dist[i].value) {
dist[i].value = dist[i - j].value + values[j];
dist[i].last = j;
}
}
}
void print(unsigned n) /* */
{ printf("\n%s%u", " : ", dist[n].value);
printf("\n :");
while (n > 0) {
printf("\n%u %u", dist[n].last, values[dist[n].last]);
n -= dist[n].last;
}
}
int main(void) {
solve(n);
print(n);
return 0;
}

taxi.c
:
: 147
:
3 31
6 58
6 58

:
1. .
2. .
3. ,
? ? ?

8.4.2.
[Timus, 1031]:
- .
, .
,
( 1).

8 -

554

.
8.4.2.
X
0 < X L1
L1 < X L2
L2 < X L3


C1
C2
C3

8.4.2. .
,
L3.
. , , . . .
.
. , :
, .
- memoization. , minPrice(k) k 3 :
1) minPrice(i1) + C1, i1 - , k,
- L1
2) minPrice(i2) + C2, i2 - , k,
- L2
3) minPrice(i3) + C3 i3 - , k,
- L3
s .
minPrice(k) = 0, k = 0, 1, , s
minPrice(k) = min(minPrice(i1) + C1, minPrice(i2) + C2, minPrice(i3) + C3), k > s
.
#include <stdio.h>
#define MAX 8000
#define NOT_CALCULATED

(unsigned long)(-1)

unsigned long minPrice[MAX];/* . */


const unsigned long dist[MAX] = {0,3,7,8,13,15,23}; /* */
/* */
const unsigned long l1 = 3, l2 = 6, l3 = 8,
c1 = 20, c2 = 30, c3 = 40;
const unsigned n = 7;
const unsigned end = 6;
unsigned start = 2;
unsigned long calc(unsigned cur)
{ unsigned i;
unsigned long price;
if (NOT_CALCULATED == minPrice[cur]) {
/* - ,
1 */
for (i = cur - 1; i >= start && (dist[cur] - dist[i]) <= l1; i--);
if (++i < cur)

8 -

555

if ((price = calc(i) + c1) < minPrice[cur])


minPrice[cur] = price;
/* - ,
2 */
for (; i >= start && (dist[cur] - dist[i]) <= l2; i--);
if (++i < cur)
if ((price = calc(i) + c2) < minPrice[cur])
minPrice[cur] = price;
/* - ,
3 */
for (; i >= start && (dist[cur] - dist[i]) <= l3; i--);
if (++i < cur)
if ((price = calc(i) + c3) < minPrice[cur])
minPrice[cur] = price;
}
return minPrice[cur];
}
int main(void) {
unsigned i;
/* */
for (i = 0; i < start; i++)
minPrice[i] = 0;
for (; i < n; i++)
minPrice[i] = NOT_CALCULATED;
/* */
start--;
printf(" : %lu\n", calc(end-1));
return 0;
}

railway.c
:
1. .
2. ,
: , , .
3. - .
? ? ? ,
?

8.4.3.
.
:
( ):
:
a1
a2
a4

a3
a5

a6

8 -

556
a7

a8

a9

a10

n n(n+1)/2 . x i- (1 i n) y
(i+1)- ,
y x. a5 a7, a8 a9. a2 a4 a5.
, n , :

;
,
, -;
.

: G(V,E), V = {a1, a2, , an(n+1)/2}


E = {(ai,aj) | ai aj }. G
n, . ,
n 1 ( )
, . . an(n+1)/2n+1, an(n+1)/2n+2, , an(n+1)/2 (
- , . . .).
, , G, .
, , ,
, .
2 3 ,
.
, . ,
. px
x k = 2, 3, , n : y
x px. px (. . x), py
y. py . , , py,
- py, , x py, px, -
px, px. ,
, . .
- .
.
k, k1. ,
k2 . . , , .
, - , .
, .
k k+1
, ,
, . :
v[x] x ( x- );
p[x] x;
pred[x] x x.

8 -

557

,
. :
1
:
1) :
p[1] = v[1];
p[x] = +, x = 2, 3 ,, n(n+1)/2.

2)

k = 1, 2,, n1:
a) p[x] x k (k < n).
y k + 1 :
p[y] = min(p[y],p[x]+v[y]).

) a p[y], x
y y:
pred[y] = x.

2
,
:
1) :
p[1] = v[1];
p[x] = +, x = 2,3,, n(n+1)/2.

2)

k = 2, 3, , n:
) p[y] y k1 (k n). x k :
p[x] = min(p[y]+v[x],p[y]+v[x],p[y]+v[x]),

y, y y x k1.
( -).
) a) p[x] y{y, y, y}, y x x:
pred[x] = y.

, N .
, N = n(n+1)/2, (n2).

. . , - , .
1:
#include <stdio.h>
#define MAX
100
#define MAX2 MAX * (MAX + 1) / 2
#define INFINITY (unsigned)(-1)
unsigned p[MAX2];
unsigned pred[MAX2];

/* I */
/* i . */

const unsigned v[MAX2] = /* */


{ 0,1,22,33,5,6,77,8,22,7,225,177,738,737,778,39,28,9,10,11,12,13 };

8 -
const unsigned n = 6;

558
/* */

void compare(unsigned ind1, unsigned ind2)


{ if (p[ind1] > p[ind2] + v[ind1]) {
p[ind1] = p[ind2] + v[ind1];
pred[ind1] = ind2;
}
}
/* */
void findMinPath(void)
{ unsigned i, j, sum;
/* */
for (p[1] = v[1], sum = 0, i = 1; i <= n; i++) {
for (j = 1; j <= i; j++) {
if (j > 1)
compare(sum + j + i - 1, sum + j);
compare(sum + j + i, sum + j);
compare(sum + j + i + 1, sum + j);
}
sum += i;
}
}
/* */
void print(const unsigned m[])
{ unsigned i, j, sum;
for (sum = 0, i = 1; i <= n; printf("\n"), sum += i++)
for (j = 1; j <= i; j++)
printf("%8u", m[sum + j]);
}
/* x */
void writePath(unsigned x)
{ printf("\n%s%u%s%u", " ", x,
" : ", p[x]);
printf("\n, (): ");
while (x != 1) {
printf("%u ", x);
x = pred[x];
}
printf("1");
}
/* */
void findMinLastRow(void)
{ unsigned i, minInd, end = n * (n + 1) / 2;
for (i = 1 + (minInd = end-n+1); i <= end; i++)
if (p[i] < p[minInd])
minInd = i;
writePath(minInd);
}
int main(void) {
unsigned i;
for (i = 0; i < (n + 3)*(n + 2)/2; i++)
p[i] = INFINITY;
printf(" :\n"); print(v);
findMinPath();

8 -

559

printf("\n :\n"); print(p);


findMinLastRow();
return 0;
}

triangle.c
: ( )
:
1
22
33
5
6
8
22
177
738
28
9

77
7
737
10

225
778
11

:
1
23
34
28
29
111
36
50
36
336
213
774
773
814
241
222
783
386

39
12

13

375
387

388

17 : 222
, (): 17 11 7 4 2 1

:
1. .
2. . ?
?
3. , .

8.4.4.
: n : c1, c2, ..., cn S.
S . c1, c2, ...,
cn .
: . F(k) , k. :

k 0

0
F (k )

min
F
(
k

c
k 0
i

i 1, 2,...,n;k ci
F(S) .
F(k) , k = 1. , F(k) k F ( ). k
, ,
. k
. , , . canJ() j- i- .
:

8 -

560

1. cj i
2. i cj
3. j i cj
( )
icj . ,
F(S), , .
(S). j1. j2
, icj1. j3 icj1cj2 .. ,
.
. findMin()
for (S) (n), canJ(),
(n). (S.n.n). ,

M, S M.n. (M.n 3). , M (n3).
, , , , , - S. , S ,
sums[]
(S.n2).
#include <stdio.h>
#define MAXCOINS 100
#define MAXSUMA
1000
struct {
unsigned num;
unsigned last;
} sums[MAXSUMA];

/* */
/* */
/* */
/* */
/* */

/* */
const unsigned coins[MAXCOINS] = {0,5,2,2,3,2,2,2,4,3,5,8,6,7,9};
const unsigned sum = 31; /* , */
const unsigned n = 14;
/* */
/* j- i- ? */
char canJ(unsigned i, unsigned j)
{ int k = i - coins[j];
if (k > 0 && sums[k].num < MAXCOINS)
while (k > 0) {
if (sums[k].last == j) break; /* j */
k -= coins[sums[k].last];
}
return(0 == k);
}
/* Sum */
void findMin(unsigned sum)
{ unsigned i, j;
sums[0].num = 0;
for (i = 1; i <= sum; i++) {
sums[i].num = MAXCOINS;

8 -

561

for (j = 1; j <= n; j++) {


if (canJ(i, j))
if ((sums[i - coins[j]].num + 1) < sums[i].num) {
sums[i].num = 1 + sums[i - coins[j]].num;
sums[i].last = j;
}
}
}
}
void print(unsigned sum)
{ /* */
if (MAXCOINS == sums[sum].num)
printf("\n .");
else {
printf("\n : %u", sums[sum].num);
printf("\n : ");
while (sum > 0) {
printf("%u ", coins[sums[sum].last]);
sum -= coins[sums[sum].last];
}
}
}
int main(void) {
printf("\n%s %u %s", " ",
sum," ?");
findMin(sum);
print(sum);
return 0;
}

coins.c
:
: 5
: 5 2 8 7 9

:
1.
, , ?
2. , .
3. .

8.4.5.
:
n (n < 1000) , 1 n.
Q[1..n] 1 n. P Q1 Q.
: P(i) = j Q(j) = i. i
P(i) .
.
, .
: , . F(i,j), -

8 -

562

, ,
i n j n . :
F i, j 1

max

k ,( i k n , P ( k ) n )

F k 1, P(k ) 1

:
F(i,j) = 0, i > n j > n
F(i,j) , F(1,1). i j n2 F(i,j)
- n
. ( , , -,
-, . . .)
, (n3) (n2).
,
nn F
.
?
F:
F(i,j) = 0, i > n j > n
F(i,j) = max(1 + F(i+1,P(i) + 1), F(i+1,j) ) P(i) j
- i P(i), , i i+1.
(n2) (n2).
- .
- ,
, . ,
, . , ( 8.2.1.),
(- :
).
.
i : F(i,1...n) F(i+1,1..n),
. F(x)
, x, x1, ..., n. T
F(x) n- :
for (i = 1; i <= n; i++)
F[i] = 1;
for (k = n; k >= 1; k--)
for (i = k + 1; i <= n; i++)
if (p[k] < p[i])
if (1 + F[i] > F[k])
F[k] = 1 + F[i];

, xP[x] iP[i] , F[x], 0, xP[x]


F[i] i .
max(F[i]) 1 i n. ,

8 -

563

, next[1..n], , F[i], 0 .
#include <stdio.h>
#define MAX 1000
unsigned F[MAX];
/* */
unsigned next[MAX];
/* */
const unsigned n = 9;
/* */
const unsigned p[MAX]={0,9,1,3,6,2,7,5,4,8}; /* . */
void solve(void)
{ unsigned k, i;
/* */
for (i = 1; i <= n; i++) {
F[i] = 1;
next[i] = 0;
}
/* */
for (k = n; k >= 1; k--)
for (i = k + 1; i <= n; i++)
if (p[k] < p[i])
if (1 + F[i] > F[k]) {
F[k] = 1 + F[i];
next[k] = i;
}
}
/* */
void print(void)
{ unsigned i, max, index;
for (max = F[index = 1], i = 2; i <= n; i++)
if (F[i] > max) {
max = F[i];
index = i;
}
printf("\n : %u\n", max);
do {
printf("%u ", index);
index = next[index];
} while (index);
}
int main(void) {
solve();
print();
return 0;
}

board.c
(n = 9):
i = 1
*

2
*

3
*

4
*

5
*

6
*

7
*

8
*

9
*

*
P(i) = 2

*
5

*
3

*
8

*
7

*
4

*
6

*
9

*
1

:
: 5
2 3 4 6 9

8 -

564

:
i = 1
*

2
*

3
*

4
*

5
*

6
*

7
*

8
*

9
*

*
P(i) = 2

*
5

*
3

*
8

*
7

*
4

*
6

*
9

*
1

:
1. .
2. .

8.4.6.
. n .
, - .
, Ti, i- . , . j (j+1)- (1 j n1) ,
, Rj, , - Tj + Tj+1.
, , .
n, Ti Rj.
, - . .
. ,
(i1)- . i- , i1- i2- . : i
i1, .
F(i),
i . :
F(i) = min(F(i1)+Ti, F(i2)+Ri1), 2 i n
i- , i1. ,
: F(0) = 0, F(1) = T1.
i Rj .
0, , :
F(i) = min(F(i1)+Ti1, F(i2)+Ri2), 2 i n
F(0) = 0, F(1) = T0
F(i) i = 1, 2, ..., n.
F(i) 1 i n,
. -,
, -, . .
F(i). F(n), , (n)
(n). .
#include <stdio.h>
#define MAXN
1000
#define MIN(a, b) ((a) < (b) ? (a) : (b))

8 -

unsigned F[MAXN];
const unsigned T[MAXN] = {8,5,3,9,2,1,4,4,1,17};
const unsigned R[MAXN] = {1,3,9,4,2,4,9,3,8};
unsigned n = 10;

565

/*
/*
/*
/*

*/
1 */
2 */
*/

/* */
void solve(void)
{ unsigned i;
F[0] = 0; F[1] = T[0];
for (i = 2; i <= n; i++)
F[i] = MIN(F[i - 1] + T[i - 1], F[i - 2] + R[i - 2]);
}
/* */
void print(void)
{ printf("\n : %u", F[n]);
do
if (F[n - 1] + T[n - 1] == F[n])
printf("\n%u", n--);
else {
printf("\n(%u,%u)", n - 1, n);
n -= 2;
}
while (n > 0);
}
int main(void) {
solve();
print();
return 0;
}

tickets.c
:
: 24
(9,10)
8
(6,7)
(4,5)
3
(1,2)

:
1. .
2. ( 8.3.1.).
3. ?

8.4.7.
: n,
k , ,
. , ,
.

8 -

566

8.4.7.,
(- v).

1
2
3

0
0
0
0

1
10
15
20

2
15
20
30

3
25
30
40

4
40
45
50

5
60
60
60

8.4.7. .
3
, e 5
5
, , . 65
, 1 0, 2 4, 3 1.
( ) -
, n. ,
.
. F(i,j), 1 i k;
0 j n. , ,
j i . (2 i k, 1 j n):
1. F(i,0) = 0, 1 i k
2. F(1, j) = maxl v(1,l), 1 l min(j, ), 1 j n
3. F(i, j) = maxl (v(i,l) + F(i1, jl)), 1 l min(j, )
: , .
: j
, , , . ,
, , - , .
: , i , ji i1
. , ,
amount[][], F(i,j)
, i j.
, - ,
, . . memoization.
#include <stdio.h>
#include <string.h>
#define
#define
#define
#define
#define

MIN(a, b)
((a) < (b) ? (a) : (b))
MAXPERCITY 100 /* */
MAXCITIES
50 /* */
MAXCARGO
200 /* . */
INFINITY
(unsigned)(-1)

unsigned F[MAXCITIES][MAXCARGO];
unsigned amount[MAXCITIES][MAXCARGO];

/* */
/* . */

8 -

567

unsigned inc;
unsigned k = 3;
/* */
unsigned n = 5;
/* */
const unsigned M = 5;
/* . */
const unsigned
{ 0, 10, 15,
{ 0, 15, 20,
{ 0, 20, 30,
};

v[MAXCITIES][MAXPERCITY] = {
25, 40, 60 },
30, 45, 60 },
40, 50, 60 }

/* */

unsigned maxIncome(unsigned city, unsigned ccargo)


{ unsigned i, max;
if (0 == ccargo)
return 0;
/* , ;) */
else if (0 == city) {
/* ccargo 1 , */
/* . */
for (i = max = 0; i <= MIN(ccargo, M); i++)
if (max < v[city][i]) {
max = v[city][i];
amount[city][ccargo] = i;
}
F[city][ccargo] = max;
return max;
}
else if (F[city][ccargo] != INFINITY) /* , */
return F[city][ccargo];/* */
else {
/* . . i */
/* (ccargo-i) */
for (i = max = 0; i <= MIN(ccargo, M); i++) {
inc = v[city][i] + maxIncome(city - 1, ccargo - i);
if (max < inc) {
max = inc;
amount[city][ccargo] = i;
}
}
F[city][ccargo] = max;
return max;
}
}
void scheduleCargo(void)
{ unsigned i,j;
for (i = 0; i <= k; i++)
for (j = 0; j <= n; j++)
F[i][j] = INFINITY;
F[k - 1][n] = maxIncome(k - 1, n);
}
void printResults(void)
{
printf("\n : %u", F[--k][n]);
for(;;) {
if (0 == n)
printf("\n %u . 0.", k+1);
else {

8 -

568

printf("\n %u . %u.", k+1, amount[k][n]);


n -= amount[k][n];
}
if (0 == k--) break;
}
if (n > 0)
printf("\n : %u", n);
}
int main(void)
{ scheduleCargo();
printResults();
return 0;
}

resource.c
:
:
3
2
1

65
1.
4.
0.

:
1. - .
2. .
3. , .

8.4.8.
"" "" . 1 365
. , : "", "", ..
, . n
"" m ""
, .
. B(d)
R(d), 1 d ,
[1;d]
"" ( ) . ,
, max(B(365), R(365)). B R (, 365 .):
1. B(0) = 0
2. B(d) = max (B(d1), R(b1) + db+1), d > 0, "" (bd)
3. R(0) = 0
4. R(d) = max (R(d1), B(b1) + db+1), d > 0, "" (bd) )
, d
:
1) d1;
2) "", d,
, "";

8 -

569

"", d,
, "".
, . , , -, .
( ), ,
.
B R d , - d, ,
, - d, .
- B R ,
, ,
. , ,
- .
d ,
, , -
. 365 ,
. n2/2 +
m2/2, . .
365 ( )
.
( 3.2.4.).
3)

#include <stdio.h>
#define MAXN
#define MAXD

5000
365

/* */
/* */

struct TZ { unsigned b, e; };
struct { unsigned cntBlue, cntRed; } B[MAXD], R[MAXD];
const unsigned n = 2; /* */
const unsigned m = 4; /* */
struct TZ blueOrders[MAXN] = { {1,5}, {12,20} };
struct TZ redOrders[MAXN] = { {2,10}, {6,11}, {15,25}, {26,30} };
/* */
void sort(struct TZ Z[], const unsigned count)
{ unsigned i, j;
struct TZ swp;
for (i = 0; i < count; i++)
for (j = i + 1; j < count; j++)
if (Z[i].e > Z[j].e) {
swp = Z[i];
Z[i] = Z[j];
Z[j] = swp;
}
}
/* */
void solveDynamic(void)
{ unsigned d, bb, be, blueIndex, redIndex;

8 -

570

/* */
B[0].cntBlue = B[0].cntRed = R[0].cntBlue = R[0].cntRed = 0;
blueIndex = redIndex = 1;
/* B[1..MAXD], R[1..MAXD] */
for (d = 1; d <= MAXD; d++) {
/* B[d] */
B[d] = B[d - 1];
for (blueIndex = 0; blueIndex < n; blueIndex++) {
if (blueOrders[blueIndex].e > d)
break;
else {
bb = blueOrders[blueIndex].b;
be = blueOrders[blueIndex].e;
if (R[bb-1].cntBlue + R[bb-1].cntRed + (be-bb+1)
> B[d].cntBlue + B[d].cntRed) {
B[d].cntBlue = R[bb - 1].cntBlue + (be - bb + 1);
B[d].cntRed = R[bb - 1].cntRed + 0;
}
}
}
/* R[d]: B[d] */
R[d] = R[d - 1];
for (redIndex = 0; redIndex < m; redIndex++) {
if (redOrders[redIndex].e > d)
break;
else {
bb = redOrders[redIndex].b;
be = redOrders[redIndex].e;
if (B[bb-1].cntBlue + B[bb-1].cntRed + (be-bb+1)
> R[d].cntBlue + R[d].cntRed) {
R[d].cntBlue = B[bb - 1].cntBlue;
R[d].cntRed = B[bb - 1].cntRed + (be - bb + 1);
}
}
}
}
}
/* */
void printResult(void)
{ if (B[MAXD].cntBlue+B[MAXD].cntRed > R[MAXD].cntBlue+R[MAXD].cntRed) {
printf("\n (): %u",
B[MAXD].cntBlue + B[MAXD].cntRed);
printf("\n : %u", B[MAXD].cntRed);
printf("\n : %u", B[MAXD].cntBlue);
}
else {
printf("\n (): %u",
R[MAXD].cntBlue + R[MAXD].cntRed);
printf("\n : %u", R[MAXD].cntRed);
printf("\n : %u", R[MAXD].cntBlue);
}
}
int main(void) {

8 -

571

sort(blueOrders, n);
sort(redOrders, m);
solveDynamic();
printResult();
return 0;
}

room.c
:
(): 25
: 11
: 14

15 1220, 210, 611, 1525 2630.


:
1.
. - : R : 15, B : 611, R : 1220 B : 2630.
2. , ?

8.4.9.

.
.
, , , ,
.
( -
-). .
, ( )
, , . ,
: ,
, .
Xij = {xi, xi+1, ..., xj}. 3 :
(1) k (k = 1, 2, ..., n) X1k , ( ) xk .
(2) k (k = n, n1, ..., 1) Xkn, ( ) xk .
(3) , .
(1) . l(k), k = 0, 1, ..., n X1k , (
) xk . s(k) . :

k 0
0
l (k )
max
l (i) k 0
1 i 0,1,...,
k 1; xi xk
s(k) . , X1k , ( ) xk ,

8 -

572

X1i xk .
, l(k) ,
. l(k),
s(k), . (2)
X (1).
. . len[x] L[x]. findIncSequence().
(2) L[]
(1).
(3) , n .
x1 xn t, x1 xt xt xn . . , back.
#include <stdio.h>
#include <string.h>
#define MAX 100
struct ST {
unsigned len; /* . i */
unsigned back; /* . */
unsigned long sum; /* */
} max1[MAX], max2[MAX];
unsigned x2[MAX], rez[MAX];
unsigned top, bestLen, bestSum;
const unsigned n = 9; /* */
const unsigned x[MAX] = {0,10,20,15,40,5,4,300,2,1}; /* */
/* */
void findIncSequence(struct ST max[], const unsigned x[])
{ unsigned i, j;
/* */
for (i = 1; i <= n; i++)
for (j = max[i].len = max[i].sum = 0; j < i; j++)
if (x[j] <= x[i])
if ((max[j].len + 1 > max[i].len)
|| ((max[j].len + 1 == max[i].len)
&& (max[j].sum + x[i] > max[i].sum)) )
{ max[i].back = j;
max[i].len = max[j].len + 1;
max[i].sum = max[j].sum + x[i];
}
}
/* */
void reverse(unsigned x2[], const unsigned x[])
{ unsigned i;
for (i = 1; i <= n; i++)
x2[i] = x[n-i+1];
}
/* */
void solve(void) {
unsigned i;
/* (1) */

8 -
findIncSequence(max1, x);
/* (2) */
reverse(x2,x);
findIncSequence(max2, x2);
/* (3) */
for (bestLen = bestSum = 0, i = 1; i <= n; i++) {
if (((max1[i].len + max2[n-i+1].len > bestLen))
|| ((max1[i].len + max2[n-i+1].len == bestLen)
&& (max1[i].sum + max2[n-i+1].sum > bestSum))) {
bestLen = max1[i].len + max2[n-i+1].len;
bestSum = max1[i].sum + max2[n-i+1].sum x[i];
top = i;
}
}
}
/* */
void buildSequence(void)
{ unsigned t, len, l;
/* */
for (l = max1[t = top].len, len = 0; t != 0; t = max1[t].back)
rez[l-len++] = x[t];
/* */
for (t = max2[n-top+1].back; t != 0; t = max2[t].back)
rez[++len] = x2[t];
}
/* */
void print(void)
{ unsigned i;
printf("\n , : %u\n",
bestLen-1);
printf("\n : %0.2f\n",
(float) bestSum / (bestLen-1));
for (i = 1; i < bestLen; i++) printf("%u ", rez[i]);
printf("\n");
}
int main(void) {
solve();
buildSequence();
print();
return 0;
}

trees.c
:
, : 7
: 11.71
10 20 40 5 4 2 1

:
1. ?
2. l(k), s(k).

573

8 -

574

3. , : ,
( 2: ).

8.4.10.
X Y n , , aibi
c(ai,bi), i = 1, 2, ..., n. ,
, .
, .
F(a,b) ,
(a,b). :

c(a1 , b1 )

F (a, b) c(a1 , b1 )
b/2

a/2
F (a i, b) F (i, b), max
F (a, b j ) F (a, j )
max max
i

1
j 1

a a1 , b b1
a b1 , b a1

F ,
F[]. F[i][j] =
(a,b) F[a][b] = F[b][a] = c(a,b). F[a][b] = ,
, .
, , , ,
, .
(n4).
#include <stdio.h>
#define MAXSIZE 100
#define NOT_CALCULATED (unsigned)(-1)
struct { /* */
unsigned value;
int action;
} F[MAXSIZE][MAXSIZE];
unsigned sizeX, sizeY; /* */
/* */
void init(void)
{ unsigned x, y;
/* */
sizeX = 13;
sizeY = 9;
/* */
for (x = 1; x <= sizeX; x++)
for (y = 1; y <= sizeY; y++) {
F[x][y].value = NOT_CALCULATED;
F[x][y].action = 0;
}
/* */
F[11][1].value = 28; F[5][3].value = 31;
F[1][2].value = 4; F[2][1].value = 2;
F[3][1].value = 7; F[10][1].value = 23;

8 -
F[3][2].value = 14;
F[5][4].value = 41;

575
F[3][3].value = 17;
F[5][7].value = 96;

}
/* (x,y) */
unsigned solve(unsigned x, unsigned y)
{ int bestAction;
unsigned i, bestSol, x2 = x / 2, y2 = y / 2;
if (NOT_CALCULATED != F[x][y].value)
return F[x][y].value; /* */
bestSol = 0;
if (x > 1) {
/* */
for (i = 1; i <= x2; i++)
if (solve(i, y) + solve(x - i, y) > bestSol) {
bestSol = solve(i, y) + solve(x - i, y);
bestAction = i;
}
}
if (y > 1) {
/* */
for (i = 1; i <= y2; i++)
if (solve(x, i) + solve(x, y - i) > bestSol) {
bestSol = solve(x, i) + solve(x, y - i);
bestAction = -(int)i;
}
}
F[x][y].value = bestSol;
F[x][y].action = bestAction;
return bestSol;
}
/* */
void printSolution(int x, int y)
{
if (x > 0 && y > 0 && F[x][y].value > 0) {
if (F[x][y].action > 0) {
printSolution(F[x][y].action, y);
printSolution(x - F[x][y].action, y);
}
else if (F[x][y].action < 0) {
printSolution(x, -F[x][y].action);
printSolution(x, y - (-F[x][y].action));
}
else
printf("(%2u,%2u) --> %2u ", x, y, F[x][y].value);
}
}
int main(void) {
init();
printf("\n %u", solve(sizeX, sizeY));
printf("\n (X,Y)-->\n");
printSolution(sizeX, sizeY);
return 0;
}

cuts.c

8 -

576

:
305
(X,Y)-->
( 1, 2) --> 4 ( 1, 2) --> 4 (11, 1) --> 28 (11, 1) --> 28 ( 3, 1) --> 7
( 3, 1) --> 7 ( 3, 1) --> 7 ( 3, 2) --> 14 ( 3, 2) --> 14 ( 5, 7) --> 96
( 5, 7) --> 96

:
- ,
- .
:
1. .
2. , .
3. ,
, ?

8.4.11.
n {x1, x2, ..., xn}, , {1, 2, ..., n}. , . .
, ,
, , .
, . . , ,
. . ,
, n ,
, .
n- n- . - , , . , .
. Fmin(k,l) , l,
k, Fmax(k,l) . Fmin(k,l)
:
Fmin(k,l) = xk , l = 1
l > 1 Fmin(k,l) - (i = 1, 2, ..., l1):
Fmin(k,i) k+i1 Fmin(k+i,li)
Fmin(k,i) k+i1 Fmax(k+i,li)
Fmax(k,i) k+i1 Fmin(k+i,li)
Fmax(k,i) k+i1 Fmax(k+i,li)
Fmax(k,l):
Fmax(k,l) = xk l = 1
l > 1 Fmax(k,l) - (i = 1, 2, ..., l1):
Fmin(k,i) k+i1 Fmin(k+i,li)
Fmin(k,i) k+i1 Fmax(k+i,li)
Fmax(k,i) k+i1 Fmin(k+i,li)
Fmax(k,i) k+i1 Fmax(k+i,li), i = 1, 2, ..., l1 l > 1

8 -

577

, k > n, - k = k n,
. Fmin(k,n)
Fmax(k,n) , k = 1, 2, ..., n.
:
(k,l) (k,i) (k+i,li), . (k,l) , . , . , . . . , , .
, |,
|, | |.
-, ,
.
?
-. Fmin
Fmax, i . -
, . , , k > n kn
. (n3), - n2 Fmin Fmax,
- (n) .
#include <stdio.h>
#define MAXN 50
#define INFINITY (int)((1 << (sizeof(int)*8 - 1)) - 1)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
struct {
long min, max;
unsigned lenMin, lenMax;
} F[MAXN][MAXN]; /* Fmin() Fmax() */
const unsigned n = 7;
/* */
const long x[MAXN] = { 0, 9, -3, 8, 7, -8, 0, 7 }; /* ( 0) */
char sign[MAXN] = { ' ', '+', '*', '*', '-', '+', '*', '-' }; /* */
/* */
long oper(long v1, char sign, long v2)
{ switch (sign) {
case '+': return v1 + v2;
case '-': return v1 - v2;
case '*': return v1 * v2;
}
return 0;
}
/* */
void calculate(unsigned beg, unsigned len)
{ unsigned i, beg2;
long val1, val2, val3, val4, minValue, maxValue;
if (beg > n)
beg -= n;
if (F[beg][len].min != INFINITY) /* */

8 -

578

return;
if (1 == len) {
F[beg][len].min = F[beg][len].max = x[beg];
F[beg][len].lenMin = F[beg][len].lenMax = 0;
return;
}
/* */
F[beg][len].min = INFINITY;
F[beg][len].max = -INFINITY;
for (i = 1; i < len; i++) {
/* F[beg][i] F[beg+i][len-i] */
calculate(beg, i);
if (beg + i > n)
beg2 = beg + i - n;
else
beg2 = beg + i;
calculate(beg2, len - i);
val1 = oper(F[beg][i].min, sign[beg2 - 1], F[beg2][len - i].min);
val2 = oper(F[beg][i].min, sign[beg2 - 1], F[beg2][len - i].max);
val3 = oper(F[beg][i].max, sign[beg2 - 1], F[beg2][len - i].min);
val4 = oper(F[beg][i].max, sign[beg2 - 1], F[beg2][len - i].max);
/* F[beg][len] */
minValue = MIN(val1, MIN(val2, MIN(val3, val4)));
if (minValue < F[beg][len].min) {
F[beg][len].min = minValue;
F[beg][len].lenMin = i;
}
/* F[beg][len] */
maxValue = MAX(val1, MAX(val2, MAX(val3, val4)));
if (maxValue > F[beg][len].max) {
F[beg][len].max = maxValue;
F[beg][len].lenMax = i;
}
}
}
/* , min/max */
void printMinMax(unsigned beg, unsigned len, char printMin)
{ unsigned i, beg2;
if (beg > n)
beg -= n;
if (1 == len)
printf("%ld", x[beg]);
else {
if (len < n) printf("(");
i = printMin ? F[beg][len].lenMin : F[beg][len].lenMax;
if ((beg2 = beg + i) > n)
beg2 -= n;
printMinMax(beg, i, printMin); /* */
printf("%c", sign[beg2 - 1]); /* */
printMinMax(beg2, len - i, printMin); /* */
if (len < n)
printf(")");
}
}
/* , */

8 -

579

void solve(void)
{ unsigned i, j;
/* */
sign[0] = sign[n];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
F[i][j].min = INFINITY;
/* */
for (i = 1; i <= n; i++)
calculate(i, n);
}
/* */
void print(void)
{ unsigned i, minIndex, maxIndex;
for (minIndex = 1, i = 2; i <= n; i++)
if (F[i][n].min < F[minIndex][n].min)
minIndex = i;
for (maxIndex = 1, i = 2; i <= n; i++)
if (F[i][n].max > F[maxIndex][n].max)
maxIndex = i;
printf("\n : %d\n", F[minIndex][n].min);
printMinMax(minIndex, n, 1);
printf("\n\n : %d\n", F[maxIndex][n].max);
printMinMax(maxIndex, n, 0);
}
int main(void) {
solve();
print();
return 0;
}

ring.c
:
: -3808
((((-8+0)*7)-9)+-3)*(8*7)
: 5040
(9+-3)*(8*((7-(-8+0))*7))

:
1. ,
: |, |, | |.
2. ?
3. Fmin Fmax.
?
4. , x c
c x.

8.4.12. -
, 10 .

8 -

580

8.6. - , i- - (i1)-. (i 2)
: X = {x1, x2, ..., xn}
-.
: , - X. ,
- , , X, -.
- X
X. 2n . -
X -.
, ,
? , - X -. .
. Xk {xk , xk+1,..., xn}, lk
rk xk , 1 k n.
Fi(k): - - Xk ,
- i (0 i 9). - - X
- F0(1), F1(1), ..., F9(1).
Fi(k) :

Fi (k ) Fi (k 1)
max F (k 1),1 F (k 1)
i
rk

k n
lk i
lk i

Fi(k) xk . lk xk
i, xk Fi(k). (?) i = lk ,
xk -
, xk rk . Fi(k) - , lk , ,
- (, i =
lk ).
,
Fi(k) , . ,
10n, ,
10 () .
, -,
. ,
(n + 20), 10n. , , ak -.
, xk . -,
, n.
#include <stdio.h>
#define MAX 100
#define BASE 10 /* */
unsigned succ[MAX]; /* */
unsigned F[BASE]; /* F[i]: . i */
unsigned ind[BASE]; /* ind[i]: i */

8 -

const unsigned n = 17; /* */


const unsigned x[MAX] = {0, 72, 121, 1445, 178, 123, 3462, 762, 33434,
444, 472, 4, 272, 4657, 7243, 7326, 3432, 3465}; /* */
/* - */
void solve(void)
{ unsigned i, l, r;
for (i = 0; i < BASE; i++)
F[i] = ind[i] = 0;
/* , 0 9 */
for (i = n; i > 0; i--) {
/* - - */
r = x[i] % BASE;
l = x[i];
while (l > BASE)
l /= BASE;
/* , */
if (F[r] >= F[l]) {
F[l] = F[r] + 1;
succ[i] = ind[r];
ind[l] = i;
}
}
}
void print(void)
{ unsigned i, bestInd;
/* - */
bestInd = 0;
for (i = 1; i < BASE; i++) /* 0 */
if (F[i] > F[bestInd])
bestInd = i;
/* */
printf("\n -: %u", F[bestInd]);
i = ind[bestInd];
do {
printf("%u ", x[i]);
i = succ[i];
} while (i > 0);
}
int main(void) {
solve();
print();
return 0;
}

domino.c
:
-: 8
121 123 33434 444 4 4657 7243 3465

581

8 -

582

:
1. .
2. ?
3. . ?

8.4.13.
: ,
:
1) - ,
-.
2) - , -.
, -
. 5 8, 3, 5, 7, 0
: 8, 3, 5, 0.
: , . .
, .
Fmin Fmax, k
. Fmin - x1, x2, , xk , xk , Fmax - x1, x2, , xk , xk .
:
1 max Fmax (i) i : 1 i k & xi x k
Fmin (k ) i k , xi xk

1 max Fmin (i) i : 1 i k & xi xk


Fmax (k ) i k , xi xk

, k = 1, 2, , n. ,
- 8.6. -,
. - -
Fmin(k) Fmax(k), k = 1, 2, , n. - - .
, k i,
(1 i, k n). ,
-. ,
.

, , . . 1 - .
, ( ) 1.
-
, . . /.
OPERATION, .
#include <stdio.h>
#include <stdlib.h>
#define MAX
1000

8 -

583

#define NO_IND
(unsigned) (-1)
#define OPERATION <
const int x[MAX] = {0,8,3,5,7,0,8,9,10,20,20,20,12,19,11}; /* 0 */
const unsigned n = 14; /* */
/* : , */
unsigned Fmin[MAX];
/* Fmin */
unsigned Fmin_back[MAX];
/* : , */
unsigned Fmax[MAX];
/* Fmax */
unsigned Fmax_back[MAX];
void calculateFMinMax(void)
{ unsigned ind, ind2;
/* */
Fmin[0] = Fmax[0] = 1;
Fmin_back[0] = Fmax_back[0] = NO_IND;
/* */
for (ind = 1; ind < n; ind++) {
Fmax_back[ind] = Fmin_back[ind] = NO_IND;
Fmin[ind] = Fmax[ind] = 0;
for (ind2 = 0; ind2 < ind; ind2++) {
/*
if (x[ind2] OPERATION x[ind] && Fmin[ind2] > Fmax[ind])
Fmax[ind] = Fmin[ind2];
Fmax_back[ind] = ind2;
}
/*
if (x[ind] OPERATION x[ind2] && Fmax[ind2] > Fmin[ind])
Fmin[ind] = Fmax[ind2];
Fmin_back[ind] = ind2;
}
}
/* 1 */
Fmin[ind]++;
Fmax[ind]++;
}

*/
{

*/
{

}
void markSolutionElements(unsigned *f1, unsigned *f2, unsigned *fInd1,
unsigned *fInd2, unsigned indF)
{ if (NO_IND == fInd1[indF])
return;
f1[indF] = f2[indF] = NO_IND;
markSolutionElements(f2, f1, fInd2, fInd1, fInd1[indF]);
}
void findSolution(void)
{ unsigned ind, bestFminInd, bestFmaxInd;
/* () - */
bestFminInd = bestFmaxInd = 0;
for (ind = 1; ind < n; ind++) {
if (Fmin[bestFminInd] < Fmin[ind])

8 -

584

bestFminInd = ind;
if (Fmax[bestFmaxInd] < Fmax[ind])
bestFmaxInd = ind;
}
/* */
if (Fmin[bestFminInd] > Fmax[bestFmaxInd])
markSolutionElements(Fmin, Fmax, Fmin_back, Fmax_back, bestFminInd);
else
markSolutionElements(Fmax, Fmin, Fmax_back, Fmin_back, bestFmaxInd);
/* */
for (ind = 0; ind < n; ind++)
if (NO_IND == Fmin[ind])
printf("%d ", x[ind]);
printf("\n");
}
int main(void) {
calculateFMinMax();
findSolution();
return 0;
}

saw.c
:
8 3 5 0 20 12 19 11

:
1. .
2. ?
3. 8.4.9.
4. .
5. . , ? ?

8.5.
8.5.1.
8.1.
,
( 8.1.)?
8.2.
, (
8.1.).
8.3.
(
8.1.)?
8.4.
, 8.2.1. .

8 -

585

8.5.
8.2.1. ,
( ).
8.6.
set[] 8.2.1.?
?
8.7.
8.2.1. , ? , .
8.8.
k .
8.2.1. ?
8.9.
( 8.2.1.) ci = 1, mi =

i M = N/2.

8.10.
, ,
last[k] ( 8.2.2.).
8.11.
, 8.2.2. ?
8.12.
,
, , ( 8.2.3.).
8.13.
,
( 8.2.3.).
8.14.
8.2.3., ,
.. , n(n 1)/2 .
8.15.
( 8.2.3.) , n?
8.16.
, ( 8.2.3.) ?
8.17.
8.2.4.?
8.18.
(1), (2) (3) 8.2.4.
8.19.
(
8.2.4.).

8 -

586

8.20.
8.2.4. A0 A6 ?
8.21.
8.2.5. ,
:
)
)
)
8.22.

8.2.5.?
8.23.
8.2.5.
8.24.
(
8.2.3.), ( 8.2.4.)
( 8.2.5.).
8.25.
- ( 8.2.6.).
8.26.
8.2.6., :
) 2.min(m,n) + (1)
) min(m,n) + (1)
8.27.
8.2.7. ,
. ,
(n).
8.28.
8.2.7. .
?
8.29.
. 8.2.7.
- ? ?
8.30.
(
8.2.8.) (nm) (min(m,n)).
8.31.
( 8.2.8.).
8.32.
, 8.2.8.,
, ,
, .

8 -

587

8.33.
8.2.8. ,
smart .
8.34.
, 8.2.8.
- ( 8.2.6.).
8.35.

( 8.2.9.)?

b[][]

8.36.
( 8.2.9.).
8.37.
, 8.2.9.
.
8.38.
(1)
8.3.1.
8.39.
(2) 8.3.1.
8.40.
, ,
(1). ( 8.3.1).
8.41.
8.3.1 - .
8.42.
8.3.1 n- n: 10, 100, 200, 500,
1000.
8.43.
, ( 8.3.2.).
8.44.
(n.k) ( 8.3.2.) ,
( 8.3.1.)?
8.45.
8.3.3. 0.0 ? ?
8.46.
8.3.3. , (n).
8.47.
8.3.3. ( 1.1.5., 8.3.2.). , ?

8 -

588

8.48.
8.3.4. .
8.49.
8.3.4.
8.50.
8.3.5. .
8.51.
8.3.5.
8.52.
8.3.4. 8.3.5.
8.53.
8.3.6. .
8.54.
8.3.6. .
8.55.
8.3.6. ?
8.56.
8.3.4., 8.3.5. 8.3.6..
8.57.
8.3.7. ?
8.58.
8.3.7. .
8.59.
8.3.8. .
8.60.
aaasbbb 8.3.8.?
8.61.

( 8.3.8.). ?
8.62.
. 8.3.8. .
8.63.
( 8.3.8.)? ?
8.64.
8.3.8., - ?
8.65.
( 8.3.8.) ? XML? ?
8.66.
8.3.9. .

8 -
8.67.

8.3.9.? ?

589

NNNNNNNNECINNxqpCDNNNNNwNNNtNNNNs,

8.68.
(
8.3.8., 8.3.9.)?
8.69.
8.3.9. , :
) ;
) ;
) -
8.70.
8.3.10. .
8.71.
8.3.10.
.
8.72.
8.3.10.
8.73.
8.4.1. .
8.74.
8.4.1.
8.75.
8.4.1. ,
? ? ?
8.76.
8.4.2.
8.77.
8.4.2. , : , , .
8.78.
8.4.2. - .
? ?
? , ?
8.79.
8.4.3.
8.80.
8.4.3. ?
?
8.81.
8.4.3., .

8 -

590

8.82.

, , ( 8.4.4.)?
8.83.
8.4.4., .
8.84.
8.4.4. ( 8.2.1.).
8.85.
8.4.5.
8.86.
8.4.5.
8.87.
8.4.6.
8.88.
8.4.6. ( 8.3.1.).
8.89.
8.4.6. ?
8.90.
8.4.7. .
8.91.
8.4.7.
8.92.
8.4.7. ,
.
8.93.
. 8.4.8. : R : 15, B : 611, R : 1220 B : 2630.
8.94.
8.4.8. , ?
8.95.
8.4.9. ?
8.96.
8.4.9. l(k), s(k).
8.97.
8.4.9. , : ,
( 2: ).
8.98.
8.4.10.
.

8 -

591

8.99.
8.4.10. ,
.
8.100.
,
, ( 8.4.10.)?
8.101.
8.4.11. , : |, |, | |.
8.102.
8.4.11. ?
8.103.
8.4.11. Fmin Fmax.
?
8.104.
, x c
c x ( 8.4.11.).
8.105.
8.4.12.
8.106.
8.4.12. ?
8.107.
- ( 8.4.12.). ?
8.108.
8.4.13.
8.109.
8.4.13.
?
8.110.
8.4.13. 8.4.9.
8.111.
, 8.4.13.
8.112.
8.4.13. , -? ?

8.5.2.
8.113.
. l1, l2, ..., ln . , ,
M . i j ,

8 -

592

, ( ,
):
j

M j i lk
k i


. , k , b1,b2,...,bk
, b31 + b32 + ... + b3k1.
.
8.114.

. ,
n n. ,
. ,
. 20
, ( 1 ). -, 20 ,
17, 12. 49 :
THI|SISAS|TR|INGOFCHARS
THI SISAS|TR|INGOFCHARS 20
THI SISAS TR|INGOFCHARS 17
THI SISAS TR INGOFCHARS 12

-, 20, 10 8,
38 :
THI|SISAS|TR|INGOFCHARS
THI|SISAS|TR INGOFCHARS 20
THI|SISAS TR INGOFCHARS 10
THI SISAS TR INGOFCHARS 8

, ,
, - .
( ) , :
- , .
(-) - . .
(-) - . .
8.115.

. 1 0,75
, 1 2 , 1 0,70
. , 1 ,
5% : 0,75.20,7 = 1,05 . , n c1,
c2, ..., cn, R nn . R[i][j]
cj, ci. ,
:
R[c1 ][ci ].R[ci ][ci ]...R[ci ][ci ].R[ci ][c1 ] ,
1

ir is s r, 1 i,r n.

k 1

8 -

593

8.116.
1 n .
:

. ,
1 , , t,
CS(t) S(t)
. , k t, t+1 (k
CS(t)).S(t) .

.
6 . t, CB(t) 6
B(t) . , t k ,
t+6 (kCB(t)).B(t).

.
. , t k ,
t+1 k .
, S, B, CS CB n
. , ,
n , (n).
8.117.
.
, . ,
. .

( 0 11), . , ( 0). ,
. ,
, .
8.118. 2
. ,
? ,
,
. , ?
8.119.
, XY. . , . , t[i][j]
XY. t[i][j] == 1, , t[i][j] == 0 .
t[][],
, .
(XY), , .
(XY), - ,
. ,
.

8 -

594

8.120. 2
. ,
XY,
, ,
t[i][j] == 1. , - (X1) +
(Y1) X1 Y1
. .
, . -
(X1) + (Y1). .
8.121.
n .
, .
.
: ti, 1 i n. L.
, ,
, . . . (
9) , , , .
. ,
. 8.2.9.
8.122. 2
, ,
hi ,
- . ,
. . ,
. . , ,
. .
8.123.
, - ?
?
- ( 5.4.2.)
( 5.4.2.)
( 5.4.2.)
( 5.4.2.)
( 5.4.3.)
( 5.5.1.)
( 5.5.3.)
( 5.5.4.)
( 5.7.1.)
( 5.7.1.)
?

...
,
,
.
,

,
.
,
,
...

9.1.
, , . : , ,
( ). ,
. ,
,
(
, 8.1.). , , :

, "", .
. , ,
, - ,
, , - , , .
,
, .
(
) , , .

, 5% - , ,

.

. , , :
m (m ),
, C = {a1, a2, ..., an}. ,
1, 2, 5, 10, 20, 50 . :
1) s = 0

9 -
2)

596

i ai (aiC), s + ai m.
2.1) , s + ai m, , . .
2.2) , i s ai.
2.2.1) s = n , . .
2.2.2) s < n, 2).

, 298
50 , 20, 5 ( 250 + 40 + 5 + 2 + 1 =
298).
, :
- ,
- . .

, ,
( 9.43.). , ,
2, 5, 20 30 40.
30 ( ), 5, . . 3
. , - : 20.
,
. , 6: 5
(
3 2).
,
, .
- , .
:
1. , : 1, 2, 5, 10, 20, 50.
2. , .

9.1.1.
, .
. p/q (
). , 7/9 :
7/9 = 1/3 + 1/3 + 1/9
7/9 = 1/2 + 1/4 + 1/36
7/9 = 1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9 + 1/9
: p q (q 0, p < q; p,qN). p/q :
p/q = 1/a1 + 1/a2 + ... + 1/an,
(ai aj, 1 i, j n, i j, ai 2, aj 2, ai, ajN).
: . , 3/7
:
3/7 = 1/3 + 1/11 + 1/231
3/7 = 1/4 + 1/8 + 1/19 + 1/1064

9 -

.

597
,

:
, ,
p/q ( 1, -
). , p/q = 7/9 - 1/2. - 1/a2,
1/2 + 1/a2 7/9, . . 1/a2 7/9 1/2, 1/a2 5/18.
- , , 1/4, :
1/a3 7/9 1/2 1/4 = 5/18 1/4 = 2/72,
. . a3 1/36, , 1/2 + 1/4 + 1/36 = 7/9. :
while (p > 1) {
____1/r__p/q;
___1/r;
p/q = p/q - 1/r;
}

. ,
1/r, p/q (q 0), . . r, 1/r p/q, r 2, q
2. r q/p. r,
q/p - , - q/p (
ceil(q/p)). ( -
, ), r,
: r = (q+p)/p;.
p/q 1/r . , p q :
p = p*r - q;
q = q*r;

, .
, p/q,
1/x, . . q % p == 0. , ,
p > 1
. (?) , .
/* q p, */
void cancel(unsigned long *p, unsigned long *q) {
if (0 == *q % *p) {
*q /= *p;
*p = 1;
}
}
void solve(unsigned long p, unsigned long q) {
printf("%lu/%lu = ", p, q);
cancel(&p, &q);
while (p > 1) {
/* 1/r, 1/r<=p/q */
unsigned long r;
r = (q + p) / p;
printf("1/%lu + ", r);
/* p/q - 1/r */

9 -

598

p = p * r - q;
q = q * r;
cancel(&p, &q);
}
if (p > 0)
printf("%lu/%lu ", p, q);
printf("\n");
}
int main(void) {
solve(3, 7);
return 0;
}

egypt.c
:
3/7 = 1/3 + 1/11 + 1/231

:
1. , - .
2. ,
1/x. ?
.
3. , . , ?
4. [Knott-1].
ai .
1 ?
5. , ? ,
: r, r q/p. r = ceil(q/p) , r .
6. , ?
7. , . ,
?

9.1.2.
: n , (,
). i : si
fi. si fi
( ), .
,
, . . , , t
- i (si t fi, 1 i n).

9 -

599

1
2
3
4
1 3 5 7 9 10 13 14

9.1.2. : .
2

9.1.2. .

[Brassard,Bratley-1996]. . 9.1.2. . 1 4 , 1 2, 2
3 . (. . ).
1:
G(V, E) n , ""
i, j (fi < sj) (i, j) ( 9.1.2.). G ( 5.4.2 )
(n2).
2:
, ( 8). F,
0 t, :
F(t) = 0, i, fi < t
F(t) = max {F ( s ) 1} , .
i 1, 2,...,n
f i t

F(t0) t max { f } .
0
i
i 1, 2,...,n

memoization ( 8) ,
. , calc[t],
t. - 2n (
). t , . calc[2*n],
: calc[i].t , calc[i].maxl.
- .
, , n.
3:
,
(n.log2n), .
, ,
fi. (n.log2n),
.

9 -

600

:
:
1) i, fi (
, fi)
2) j, sj fi (. . "" ),
. 1) , ( 9.1.2.).

(1)

1
2
3
4
5
6
7

(2)

2
1
6
4
7
3
5

9.1.2. .
9.1.2. (2) (1), fi.
2, 1 6, 4, 7, 3
5. - :
___1;
i = 1; j = 1;
while (j <= n) {
j++;
if (s[j] > f[i]) {
___j;
i = j;
}
}

(, fi).
e .
#include <stdio.h>
#define MAXN 100
const unsigned n = 7;
const unsigned s[MAXN] = { 3, 7, 5, 9, 13, 15, 17 };
const unsigned f[MAXN] = { 8, 10, 12, 14, 15, 19, 20 };
void solve(void)
{ unsigned i = 1, j = 1;
printf(" : %u ", 1);
while (j++ <= n)
if (s[j - 1] > f[i - 1]) printf("%u ", i = j);
printf("\n");
}
int main(void) {
solve();
return 0;
}

aselect.c
:

9 -

601

: 1 4 6

:
1. ,
, .
prenum[], prenum[j]
j. - j
prenum[j]. .
2. 1 ( - ).
3. 2 ( , 8).
: - () - ().
4. , 1 .
5. , 2 .
6. , 3 .
7. , . 1, 2 3 ?

9.1.3.
: , n .
: , , ,
(i, j) , i j "
".
.
, .
( 5.8.1., 6.3.2.). , ,
, ,
( .
-, ,
).
1:
.
.
, . ,
, :

. -
, .
2:
. ,
, .
, .
a, [Culberson-1993][Wai-2000].
, -, : 1
solve1(), 2 solve2(). .

9 -
#include <stdio.h>
#define MAXN 200
const unsigned n = 6;
const char A[MAXN][MAXN] = {
{ 0, 1, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 0, 1 },
{ 0, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 1, 0, 1, 0, 0 }
};
unsigned color[MAXN];
/* */
void solve1(void)
{ unsigned i, j, c;
/* i - */
for (i = 0; i < n; i++) {
c = 0;
do {
c++;
for (j = 0; j < n; j++)
if (A[i][j] && color[j] == c) break;
} while (j < n);
color[i] = c;
}
}
void solve2(void)
{ unsigned c = 0, cn = 0, i, j;
/* , ,
* .., */
while (cn < n) {
c++;
for (i = 0; i < n; i++) {
if (!color[i]) {
int flag = 1;
for (j = 0; j < n; j++)
if (A[i][j] && color[j] == c) {
flag = 0;
break;
}
if (flag) {
color[i] = c;
cn++;
}
}
}
}
}
void showColor(void)
{ unsigned i;
for (i = 0; i < n; i++) printf("%u-%u; ", i + 1, color[i]);

602

9 -

603

printf("\n");
}
int main(void) {
unsigned i;
printf("
for (i = 0; i < n;
solve1();
showColor();
printf("
for (i = 0; i < n;
solve2();
showColor();
return 0;
}

1: \n");
i++) color[i] = 0;

2: \n");
i++) color[i] = 0;

colorg.c
:
1:
1-1; 2-2; 3-1; 4-1; 5-2; 6-3;
2:
1-1; 2-2; 3-1; 4-1; 5-2; 6-3;

, ( ,
), ,
. , (
, e
).
: , , .. , , ( ),
, ( 9.1.3.).

9.1.3. .
:
void treeColor( i, int color) {
i = color; /* i color */
for ( j i) {
treeColor(j, !color);
}

9 -

604

}
main() {
treeColor(root, 0); /* */
return 0;
}

, - (
, ?), ,
. V1 , V2
( 9.1.3.).

V1

V2

9.1.3. .
.
:
1. 1 n.
. ?
, , ,
.
2. 1 ,
. ( ) . ?
3. 1 2.
4. , .

9.1.4.
(
5.7.1) . ,
, : ,
, ()
(). ,
( ) ,
, .
( ,
), , , , . . ,
k "" ,

9 -

605

( k). :
( ).
k ek ,
Di Dj. , , ek
-.
, ,
er (- ek ), Di Dj,
(er er) Di Dj Dr (Dr =
E\(DiDj):
1) , ,
, : - ,
er ek .
2) 9.1.4. .
ek

Di
er1

Dj
er2

Dr

9.1.4. , .
, er er ek . , er, er
ek , - ( , er er ek Di Dj,
ek ).
(
[-1996]), , , . , - .
:
- .

9.1.5.

.
, ( 6.4.1., 8.2.1.)
:

N , mi ci.

M ( ).
( 01 , ).
,
. ,
,
. , , ( ) ..

9 -

606

( ) ,
.
, , "": - (. .
ci/mi , , ), -
.., "" . - , . 9.1.5.
.

ci

1
2
3

25
12
16

mi
( )
10
8
8

(ci/mi)
2,5
1,5
2,0

9.1.5. 16 .
- ( 1) 10
( 25). 6 ,
6 3 (6 2 = 12),
( ) 25 + 12 = 37.
, , ,
. .
k j1,j2,...,jk i1,i2,...,it.
, ,
imax, (cimax/mimax). , ,
: - ,
( > 0) , k,
imax.
,
. sort() , solve()
, - . .
#include <stdio.h>
#define MAXN 1000
const
float
float
const

unsigned n = 3;
c[MAXN] = { 25, 12, 16 };
m[MAXN] = { 10, 8, 8 };
float M = 16;

/*
/*
/*
/*

*/
*/
*/
*/

float ratio[MAXN];
void swap(float *a, float *b)
{ float s = *a; *a = *b; *b = s; }
/* */
void sort(void)
{ ...
}
/* */
void solve(void)
{ unsigned i = 0;

9 -

607

float T = 0, V = 0;;
while (T + m[i] <= M) {
/* , */
printf(" 100%% %.2f");
printf(" %.2f \n", c[i], m[i]);
T += m[i]; V += c[i];
i++;
}
printf(" %.2f%% %.2f %.2f \n",
((M - T) / m[i]) * 100, c[i], m[i]);
V += (M - T) * (c[i] / m[i]);
printf(" : %.2f\n", V);
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) ratio[i] = c[i] / m[i];
sort();
solve();
return 0;
}

fracknap.c
:
100% 25.00 10.00
75.00% 16.00 8.00
: 37.00

: "" 0-1 ( NP-). , , 9.1.5.:


1 25 (
). :
2 3 - : 12 + 16 = 28.
:
1. , 0-1
.
2. ratio[] ?
solve(). : a/b c/d ad bc.

9.1.6.
.
n l1, l2, ... , ln .
, ,
, ( ) .
K1
l1

K2
l3

K3

K4

l2

l4

Kn
l n

9.1.6. (K1 = 1, K2 = 3, K3 = 2, ...).


( 9.1.6.), ( l2),
"" l1 l3.

9 -

608

p1, p2, ..., pn, 0 pi 1, 1 i n,


n

p
i 1

1 . , 0,5 , ,

, . K1, K2, , Kn
T,
, :
n
i

p Ki l K j

i 1
j 1

T
n
, T.
. , -
, - .
- , -
( "" -, ).
: ,
Ki, pKi/lKi .
: , Ki Kj . .
-
: n .
t1, t2, ..., tn. ,
, . .
n

T
i 1

i 1

t
j 1

Kj

( K1, K2, , Kn , ).

: , - (. . ti). ,
, (p1 = p2 = ... = pn = 1 ).

n
:
1. .
2. .

9.1.7.
n . , 1. i (1 i n)
: vi di. ,
, ( . deadline). ..
, - di- .
, .
9.1.7. 5 .
9.1.7.
i
vi
di

1
40
1

2
30
2

3
15
1

4
20
1

5
50
2

9 -

609

9.1.7. .

(1)

(2)

(3)

(4)

(5)

40

30

15

20

50

(1,2) (1,5) (2,5) (3,2) (3,5) (4,2) (4,5) (5,2)


70

90

80

45

65

50

70

80

9.1.7. .
, (1,3), (2,4) .. , 3 4 1. , ( 90), (1,5).
, , :
i (1 i n) j (1 j n) , dj
i vj . , .
-, 1 5 50 (
). , , , dj
2, 2. 50 + 30 = 80, .
,
:
9.1. k ,
, .

, , , , .
A = {t1, t2, ..., tk1} . ,
, A tk :
, i- ( i = 1,2,...,n)
i ( ).
index[j] ( 0) ,
i

(j+1)- . i S index[ j ] S i+1,


j 0

tk .
, . , v[n] d[n], . -
. ,
, k (k = 1, 2, ..., n),
. ,
, -: index[]
k index[d[k]] .
taken[] ,
. (n2).
5,
1, 90, . :
#include <stdio.h>
#define MAXN 1000
const unsigned n = 5;
const unsigned v[MAXN] = { 50, 40, 30, 20, 15 };
const unsigned d[MAXN] = { 2, 1, 2, 2, 1 };
const unsigned p[MAXN] = {5,1,2,4,3}; /* . */

9 -

610

unsigned index[MAXN], taken[MAXN], tn;


char feasible(unsigned k)
{ unsigned s = 0, i;
for (i = 0; i < n; i++) {
s += index[i];
if (i == d[k] - 1) s += 1;
if (s > i + 1) return 0;
}
return 1;
}
void solve(void)
{ unsigned k, i, income;
for (k = 0; k < n; k++)
if (feasible(k)) {
taken[tn++] = k;
index[d[k] - 1]++;
}
printf(" : ");
income = 0;
for (i = 0; i < tn; i++) {
printf("%u ", p[taken[i]]);
income += v[taken[i]];
}
printf("\n : %u\n", income);
}
int main(void) {
unsigned i;
for (i = 0; i < n; i++) index[i] = 0;
tn = 0;
solve();
return 0;
}

schedule.c
:
: 5 1
: 90

:
1. , -
.
2. , , , , .
, :
) ( for solve())
)

9.1.8. . .
6 ( 6.3.4.) :
nn , -

9 -

611

. ,
.
, . , n2 ( ):
1) (1, 1).
2) , (x', y')
, :
(x', y') (x, y).
(x',y') .
,
(x', y'), .
( 9.1.8.) ,
66, :
I)
(1,1) (2,3) (3,2)
(2,3).
II)
(1,5), (3,5), (4,4), (4,2) (3,1). .
: (1,5).
III)
(1,5) (3,4) (3,6): (3,6) ..
: (x,y) (, ), (1,1) . , ,
6.3.4., , (1,1) .

I.

1 2 3 4 5 6
1 K
5
2
5
3
4
5
6
2

1
K

II
.

K
2

K
5
6

3
2

III
.

9.1.8. 66.

9 -

612

. countMoves(x,y)
, (x, y). ,
n21 : countMoves()
, (
, ).
.
#include <stdio.h>
#define MAXN
100
#define MAX_MOVES
8
const unsigned n = 12;
const int moveX[MAX_MOVES] = { +1, -1, +1, -1, +2, +2, -2, -2 };
const int moveY[MAX_MOVES] = { +2, +2, -2, -2, +1, -1, +1, -1 };
int a[MAXN][MAXN], x, y, p;
int countMoves(int x, int y)
{ int i, number = 0;
if (x < 0 || y < 0 || x >= n || y >= n || a[x][y] != 0)
return MAX_MOVES + 1; /* */
for (i = 0; i < MAX_MOVES; i++) {
int nx = x + moveX[i], ny = y + moveY[i];
if (nx >= 0 && ny >= 0 && nx < n && ny < n && a[nx][ny] == 0)
number++;
}
return number;
}
void solve(void) {
unsigned i, j, n2;
/* */
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
a[i][j] = 0;
x = 0;
y = 0;
a[0][0] = 1;
p = 1;
/* "" , */
n2 = n * n;
while (p < n2) {
int min = MAX_MOVES + 1, choose;
for (i = 0; i < MAX_MOVES; i++) {
int temp = countMoves(x + moveX[i], y + moveY[i]);
if (temp < min) {
min = temp;
choose = i;
}
}
x += moveX[choose];
y += moveY[choose];
a[x][y] = ++p;
}
/* */
for (i = 0; i < n; i++) {

9 -

613

for (j = 0; j < n; j++) printf("%4d", a[i][j]);


printf("\n");
}
}
int main(void) {
solve();
return 0;
}

knightg.c
:
1
62
23
94
59
64
21
46
57
42
19
44

24 61 96
3
95
2 25 92
60 93 144 97
63 98 89 140
22 139 100 129
99 88 133 138
58 65 128 101
55 102 87 66
20 47 54 103
45 56 67 50
48 43 40 17
41 18 49 52

26
141
90
143
134
127
132
77
86
53
68
39

91
4
135
130
137
106
121
104
123
78
51
16

110
27
142
115
126
131
124
83
76
85
38
69

5
114
109
136
107
120
105
122
79
70
15
72

28 31 112
111
6 29
30 113 32
119 108
7
116 33 118
125
8 81
82 117 34
75 80
9
84 35 74
73 10 13
12 71 36
37 14 11

( ),
. , . , 6 , ,
NP- () .
, , ( 6.3.4.),
, .
, (
), ,
. n- , :
9.2. 2n ,
n - n, G n .
n- n = 1, 2, 3 4 9.1.8.

9 -

(0,0)

(1,0)

(0,1)

(1,1)

n=2

(0)

614

n=3

(1)

n=1
n=4
9.1.8. 1, 2, 3 4- .
n- . n = 1
(0) (1).
n = 2 (0,0), (0,1), (1,1) (1,0). n = 3
.. (.. n- ) n- , n- 0 1 , i j , n-
.
( ) n-
, , ,
- . [, , -1980].
:
n=1
0
1

n=2
0
1
1
0

0
0
1
1

n=3
0
1
1
0
0
1
1
0

0
0
1
1
1
1
0
0

0
0
0
0
1
1
1
1

i1, i2, ..., i n n = k.


2
i1
i2
...

i2 n

9 -

615

n = k + 1 , n = k
0, n = k 1:
i1 0
i2 0
...
in0
2

i2 n 1
...
i2 1
i1 1

, :
#include <stdio.h>
#define MAXN 1000
/* , n- () */
const unsigned n = 3;
char a[MAXN];
void print(void)
{ unsigned i;
for (i = 1; i <= n; i++) printf("%d ", (int) a[i]);
printf("\n");
}
void forwgray(unsigned); /* prototype */
void backgray(unsigned k)
{ if (0 == k) { print(); return; }
a[k] = 1; forwgray(k - 1);
a[k] = 0; backgray(k - 1);
}
void forwgray(unsigned k)
{ if (0 == k) { print(); return; }
a[k] = 0; forwgray(k - 1);
a[k] = 1; backgray(k - 1);
}
int main(void) {
forwgray(n);
return 0;
}

hamgray.c
:
1. -
(m2.n2), m e ( -
2
MAX_MOVES): n , m countMoves(),
(m). , n2 ,
(n2)?
2. ,
, 6.3.4.? ?

9 -

616

3. .

9.2.
.
, "": ,
, ""
.
k (kN) ,
int random(k), 0 k
1.
random() (
[Knuth-2/1968]). , ,
<stdlib.h>, . ,
.
1: : m a[n].
(
4.3.), : a[i] (i = 1,2,...,n) m. (n),
- . .
:
1) a[i] : i = random(n).
1.1) a[i] == m, .
1.2) a[i] != m, 1.
, (n)
1/n. - ,
: ,
random() , , , "",
, . random() , ,
, .
. , taken[n], , number,
. i,
taken[i]==0 (.. ),
taken[i]==1 number 1. , number n, , , .
2: .

.
, .
, .
, - . ,
" ", .
, ,
:
3: NP- ( 6) , ,
. , -

9 -

617

( 6.3.), ,
.
9.2., D-D2-D6-D7,
D1 ( , ),
. ,
D1. , ,
:
, . ,
() .
D2, D1, e 0,5.
0,75, 0,875 (?) .., ..
, .
D

D1

D3

D4

D2

D5

D6

D7

9.2. .
, , , . ( ) ,
.
.
:
, .

9.2.1.
( ) ( , "" ).
"", .
, ( ,
, ,
- ). ,
, , ( ,
).

9 -

618

-

n . k p1, p2, ..., pk (2 pi n ) n
, n . :
1:
for (i = 1,...,k)
if (n % (random(sqrt(n))+2) == 0) {
return n__;
}
return n__;

, , - n , n.
k , n , .
p
, .. . ( 1.1.3.),
, , - n . q
n, -
[2,

n .
n ]. n q ,
n

: 1 q . k :

1 q ( ). ,

p = 1 1 q .

1p , , n .
p ,
(- p n).
, , p-, . . p.
1 . -
( -) .
:
. () n . an1 % n = 1 a = 1,2,...,n1.
: n
a (1 < a < n), an1 % n 1, , n :
2:
for (i = 1,2,...,k) { /* k */
a = random(n-1) + 1;
if ((an-1) % n != 1) {
return n__;
}
}
return n__;

9 -

619

p, , 2
p-. , , > 0
, 2 , , - [Brassard,Bratley1996].
, p-, ,
. -
. n , n > 4 ( n , ).
9.3. n, n > 4. 2st1,
s t , s > 0, n > 1, t . a, 1 < a < n1.
n a, at % n = 1,
i (0 i < s) , a 2 t % n = n1.
i

. a (1 < a < n1) n


, n . n , - 0,75.
3:
for (i = 1,2,...,k) { /* k */
a = random(n-3) + 2;
if (n_______a) {
return n__;
}
}
return n__;

, 0,75, . .
0,75-. , 3 k = 4 (. .
4 ) , n , n , - 99%.
, 1000 , - 10-100 [Brassard,Bratley1996].
3 n
a. :
1) s t ( 9.3.):
s = 1; t = n-1;
while (t % 2 != 1) { s++; t /= 2; }

2) at % n = 1:
x = power(a,t) % n;
if (1 == x) return (n___);

3) i (0 i < s), a 2 t % n = n1:


i

for (i = 1,2,...,s-1) {
if (n-1 == x) return (n___);
x = x*x % n;
}
return (n__);

, 2) x = at % n ,
: at
, x [0, n1]. , :
a.b % p = [(a % p).(b % p)] % p ,

9 -

620

, (,
.). at % n :
at % n = (at1.a) % n = [(at1 % n).(a % n)] % n
at1 % n (!),
a2 % n = a.a % n= [(a % n).(a % n)] % n
bigmod(a,t,n).
:
#include <stdio.h>
#include <stdlib.h>
const unsigned n = 127; /* n */
const unsigned k = 10; /* a */
/* power(a,t) mod n; */
unsigned long bigmod(unsigned long a, unsigned long t, unsigned long n)
{ return (1 == t) ? (a % n) : (bigmod(a, t - 1, n) * (a % n)) % n; }
char strongRandom(unsigned long n, unsigned long a)
{ unsigned long s = 1, t = n - 1, x, i;
/* */
if (n < 2) return 0;
if (2 == n) return 1;
/* 1) */
while (t % 2 != 1) {
s++;
t /= 2;
}
/* 2) x = power(a,t) mod n; */
x = bigmod(a, t, n);
if (1 == x) return 1;
/* 3 */
for (i = 0; i < s; i++) {
if (x == n - 1) return 1;
x = x * x % n;
}
return 0;
}
char isPrime(unsigned long n)
{ unsigned i;
for (i = 1; i <= k; i++) {
int a = rand() % (n - 3) + 2;
if (!strongRandom(n, a)) return 0;
}
return 1;
}
int main(void) {
printf(" %u e %s.\n", n, (isPrime(n)) ? "" : "");
return 0;
}

prime_mc.c
,
, (9.4.).

9 -

621

:
1. 1, 2 3.
2. 1 2.
3. , 3 0,75-.

9.2.2.
- .
,
"". ,
, , ,
, .
-
.
, , . ,
. , ,
, 1768 .
.

2r
9.2.2. r.
, S r S = r2.
r, 2r ( 9.2.2.).
r2/(2r)2 , p
,
r2/(2r)2. : t
, ( ,
- ). k,
t, p, -. ,
, :

4.k .r 2 4.k
k .r 2 , . .

2
t
t.r 2
t 2r
, ,
, t.
- , - t - r ( - r
-, t -
). , r , r2
long (
).
,
:
#include <stdio.h>

9 -

622

#include <stdlib.h>
#include <math.h>
int main(void)
{ long t = 1000000; /* */
long r = 200; /* */
long r2 = r / 2;
long k = 0, i;
for (i = 0; i < t; i++) {
long a = (rand() % r) - r2 + 1;
long b = (rand() % r) - r2 + 1;
if (sqrt(a * a + b * b) <= r2) k++;
}
printf(" p = %.2f\n", (4.0 * k) / t);
return 0;
}

pi.c
, 1 ,
100 [Brassard,Bratley1996].
, , [-1994].
( ),
.
:
1. , -
- .
2.
k- k = 2,3,4,5,6. , ,
1 ,
100 ?

9.2.3.
,
. ,
, .
- ,
-. -
- .
" -".
( 5.4.4.).
: G(V, E) (
) . .
NP-
( n ), n! , 6,
, ,
.

9 -

623

9.4. ,
, .
P = {H1, H2, ..., Hq} q .
- "". 1 n, ,
. H 9.2.3. 5 .
( ) 1-2-3-45 (25), 3-4-5-1-2 (49), 5-3-1-4-2 (35).
:
() ( -
)
(). ,
. , .
1
17

10

2
11
12

-12

3
12
-5

8 7

19

9.2.3. 5 .
, ,
P, - ,
Hi = (i1, i2,..., in)P Hj = (j1, j2,..., jn)P :
k r () : (i1, ..., ik-1, jk , ..., jr, ir+1, ...,
in) (j1, ..., jk-1, ik , ..., ir, jr+1, ..., jn).
, 2-3-1-4-5, 5-1-3-4-2 k = 2, r = 4,
2-1-3-4-5 5-3-1-4-2, 1-2-3-4-5, 1-3-5-4-2 k = 2, r = 3,
1-3-5-4-5 1-2-3-4-2.
, , , . , . - P,
, . . - . ,
, , .
. , ( - )
P . - ""
. .
- (
,
, ). ,
,
.
.
:

initGraph(), n (
, ).
randomCycle(), .

9 -

624

evaluate(), (
).
combine(), .
mutate(), , ,
.
reproduce() .
, , .

-, combine() (n )
PSIZE/2 (PSIZE , n).
, - PSIZE (
, (n.PSIZE)), -
. reproduce() (n2.PSIZE).
maxSteps reproduce(), ..
2

, . :
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100
/* , psize % 4 == 0 */
#define PSIZE 200
const unsigned long maxSteps = 1000;
const unsigned n = 20;
/* */
char A[MAXN][MAXN];
/* */
int population[PSIZE][MAXN]; /* */
int result[PSIZE];
/* */
void initGraph(void)
{ unsigned i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
A[i][j] = (rand() % 100) + 1;
}
void randomCycle(int t)
{ char used[MAXN];
unsigned i;
for (i = 0; i < n; i++) used[i] = 0;
for (i = 0; i < n; i++) {
int p = (rand() % (n - i)) + 1;
int j = 0;
while (p > 0) {
while (used[j]) j++;
p--; j++;
}
population[t][i] = j - 1;
used[j - 1] = 1;
}
}
int evaluate(int t)
{ unsigned i;
int res = 0;

9 -
for (i = 0; i < n - 1; i++)
res += A[population[t][i]][population[t][i + 1]];
return res + A[population[t][n - 1]][population[t][0]];
}
/* q1,q2 p1,p2 */
void combine(int p1, int p2, int q1, int q2)
{ int uq1[MAXN], uq2[MAXN];
unsigned i, j, k;
k = (rand() % (n - 1)) + 1; /* k */
for (i = 0; i < n; i++) {
uq1[i] = 0;
uq2[i] = 0;
}
for (i = 0; i < k; i++) {
population[q1][i] = population[p1][i];
uq1[population[p1][i]]++;
population[q2][i] = population[p2][i];
uq2[population[p2][i]]++;
}
for (i = k; i < n; i++) {
if (0 == uq1[population[p2][i]]) {
population[q1][i] = population[p2][i];
uq1[population[p2][i]]++;
}
else {
for (j = 0; uq1[j] != 0; j++);
population[q1][i] = j;
uq1[j]++;
}
if (0 == uq2[population[p1][i]]) {
population[q2][i] = population[p1][i];
uq2[population[p1][i]]++;
}
else {
for (j = 0; uq2[j] != 0; j++);
population[q2][i] = j;
uq2[j]++;
}
}
result[q1] = evaluate(q1);
result[q2] = evaluate(q2);
}
void mutate(void) {
unsigned i, k;
/* , "" */
for (i = 0; i < PSIZE - 1; i++) {
int flag = 0;
for (k = 0; k < n; k++)
if (population[i][k] != population[i + 1][k]) {
flag = 1;
break;
}
if (!flag) { /* i */
int p1 = rand() % n;
int p2 = rand() % n;

625

9 -
int swap = population[i][p1];
population[i][p1] = population[i][p2];
population[i][p2] = swap;
result[i] = evaluate(i);
}
}
}
void reproduce(unsigned s)
{ unsigned i, j, k, swap;
/* - ,
*
*/
for (i = 0; i < (PSIZE-1)/2; i += 2) {
/* randomCycle(i); */
combine(i, i+1, PSIZE-i-1, PSIZE-i-2);
result[i] = evaluate(i);
}
/* */
for (i = 0; i < PSIZE - 1; i++) {
for (j = i + 1; j < PSIZE; j++) {
if (result[j] < result[i]) {
for (k = 0; k < n; k++) {
swap = population[i][k];
population[i][k] = population[j][k];
population[j][k] = swap;
}
swap = result[i];
result[i] = result[j];
result[j] = swap;
}
}
}
if (maxSteps 1 == s) return;
mutate();
}
int main(void) {
unsigned i, j, s;
int minRandom;
initGraph();
/* */
minRandom = n*101;
for (s = 0; s < maxSteps; s++) {
for (i = 0; i < PSIZE; i++) {
randomCycle(i);
result[i] = evaluate(i);
}
for (j = 0; j < PSIZE; j++)
if (result[j] < minRandom)
minRandom = result[j];
}
printf(" %ld : %d\n",
PSIZE*maxSteps, minRandom);
/* */

626

9 -

627

for (s = 0; s < maxSteps; s++) reproduce(s);


printf("- , : \n");
for (i = 10; i > 0; i--) printf("%d, ", result[i]);
printf("%d\n", result[0]);
return 0;
}

tspgenet.c
:
200000 : 487
- , :
297, 292, 292, 292, 292, 292, 292, 292, 292, 289, 289

. ( 20 ) ,
:
:
1. , 6,
, ,
?
2. ( initGraph()). , .
3. - , , :

9.3.
- , . :

,
.
, ( ), , ( ).
9.5. n A, . , p(n),

max{ C , C' } p(n),

C' C
C' - , A, C .
, p(n) ( p),
n .
.

9 -

628

9.3.1.
9.6. G(V, E) -
D, : (i,j)E i
j D. D G.
, , ( , 5.7.3. ,
).
NP-
. -
- , . . p(n).
1

9.3.1. n .
1:
D - , . : D = . D
i . i,
. , .
9.3.1.
1 , 1
. , , 1,
2? n2 ,
, g = n1,
d = 1. , n ( ),
g. , p,
, , . .
max { g/d, d/g } p,

max { g/d, d/g } n1,
p(n) = n1, .. p(n) n.
1 ,
n1 ,
- . , , - 2 - .
2:
D , ( D = ).
(i, j) . i j D,
, i j. ,
.

9 -

629

9.3.1. 6 .
9.3.1. :

(1, 2), (2, 3) (1, 5),


D 1 2.
(3, 5) (3, 4) (5, 6), D
3 5.
(4, 6) ,
4 6. {1, 2, 3, 4, 5, 6}, 6, - :
{2, 5, 4}.

, p = 2:
D' , D ,
2. , | D | 2. D

| D' |
i j, (i, j).
S, |D| = 2|S|. :
S ,
. ,
(i, j) , . . (i, j)
iD', jD'. , S D',
S , D' S, .
. |S| |D'|. |S| |D'| |D| = 2|S| , |D| 2|D'|, .
NP- ( 0-1 ) (. approximation schemes), ( > 0)

, - [Brassard,Bratley1996].
:
1. 1 2.
2. 1 2.
3. 1, , - , 1 9.1.3.
?

9.4.
9.4.1.
9.1.
, 9.1.
: 1, 2, 5, 10, 20, 50.

9 -

630

9.2.
, 9.1. .
9.3.
, 9.1.1. .
9.4.
9.1.1. ,
1/x. ?
.
9.5.
( 9.1.1.),
. ,
?
9.6.
[Knott-1].
ai .
1 ? ( 9.1.1.)
9.7.
9.1.1., ? ,
: r, r q/p. r = ceil(q/p) , r .
9.8.
( 9.1.1.),
?
9.9.
( 9.1.1.)
, . , ?
9.10.
, 9.1.2.
, .
prenum[], prenum[j]
j. - j
prenum[j]. .
9.11.
1 9.1.2. ( -
).
9.12.
2 9.1.2. ( , 8).
: - () - ().
9.13.
, 1 9.1.2. .
9.14.
, 2 9.1.2. .

9 -

631

9.15.
, 3 9.1.2. .
9.16.
, ( 9.1.2.)
. 1, 2 3
?
9.17.
9.1.3.
1 n.
.
? , ,
, .
9.18.
1 9.1.3. , . (
) .
?
9.19.
1 2 9.1.3.
9.20.
, ( 9.1.3.).
9.21.
9.1.4. - .
9.22.
, 9.1.5.
0-1 .
9.23.
ratio[] 9.1.5.?
solve(). : a/b c/d ad bc.
9.24.
9.1.6.
.
9.25.
9.1.6. .
9.26.
, 9.1.7. .
9.27.
, 9.1.7. , , , . , :
) ( for solve())
)

9 -

632

9.28.
9.1.8.
(m2.n2), m e ( -
2
MAX_MOVES): n , m countMoves(),
(m). , n2 ,
(n2)?
9.29.
,
, 6.3.4.? ?
9.30.
9.1.8.
9.31.
, ( 9.2.).
9.32.
1, 2 3 9.2.1.
9.33.
1 2 9.2.1.
9.34.
, 3 9.2.1. 0,75-.
9.35.
9.2.2., - - .
9.36.

( 9.2.2.) k- k = 2,3,4,5,6.
, , 1 ,
100 ?
9.37.
, 6,
, ,
( 9.2.3.)?
9.38.
9.2.3. ( initGraph()). , .
9.39.
( 9.2.3.) -
, :


9.40.
1 2 9.3.1.

9 -

633

9.41.
1 2 9.3.1.
9.42.
1 9.3.1.,
, - , 1
9.1.3. ?

9.4.2.
9.43.
N,
C = {a1, a2, ..., an}, :
ai 2.ai-1, i = 2, ..., n, a1 = 1.
. . .
, ,
, .
9.44.
,
, {1, c, c2, c3, ..., ck }, c 2, k 0.
9.45.
( 9.1.8.),
moveX moveY , . . ,
, - ?
9.46.
n . ,
1 , .
: pl - (. . - x ).
, . ,
, pl : ,
, , .
, , ,
() .
9.47.
k , n .
i . ,
,
.
9.48.

, .
.

9 -

634

9.4.2. 4 .
. , , 9.4.2.: ( ), , : 1: {1}; 2: {1, 2, 3, 4}; 3: {1, 4}; 4: {1, 4}.
, , .
:
5, .
, .
9.49.
:
.
: si fi. , :

.
, , : ( ), ( ),
..

9.50.
A, A A.
, A A A.
9.51.
A, A.
A A. , .
9.52.
( , , 3 )
h, . . h .
:

.
, -
.
,
. , , , , 3 h
. .
9.53. 8
( 6.3.5.), .
6.3.5. .

9 -

635

9.54. k
G(V, E) H k . , H
.
.
9.55.
n (), li (
). (. . )
i+1 (i = 1,2, ..., n1) , i.
L ( ). ,
(
, , ).
9.56
nm.
11. 11, 22, 33, 44,
55 66. ,
.
9.4.2. , 4 , ).

a) 10

) 6

) 4

9.4.2. 86.
9.57.
G(V, E). G .
: , : - [-1996].
.
, ( ) ..
, .

, .
p(n),
.
, 2.

9.58. [Timus, 1025]


, , :
1 , .
2 , , .
: n , a mi (1 i n)
i- ( ). , , .
: 3, 5, 7 5 , 6
3 1- 3- .
2:1 ( , 6:11 ).

9 -

636

: ( ), -
,
-. , , :

: m1, m2, ..., mn.

n
1
2

mi

1 .
2

i 1

10


, ...
~

10.1.

.
2-3 ( 180-360 KB) ,
10-20 MB, . ,
,
. -
, , ,
. , :
.
, - , - . (COMPRESS, PKZIP, ARJ, AIN, RAR, WinZIP .),
,
. -
Stacker, Double Space, Drive Space .

(GIF, JPEG, TIFF), (WAV, MP3) (MPEG, AVI, DivX).
-, , -
.
,
( 7- ).
, ,
, ( ,
.). - .
? , . , , -
, - .
:
, .
,
. () - ().
, -. , , , ,

10 -

638

. :
, .
(-
), . , , ,
. , , . . ,
,
.

10.2.
,
. ,
,
.
. , , , . .
.
,
. :
, - ,
. -
.
, , :
, .
, -
, : , ,
.
, .
, , - 6 :

A
B
C
D
E
F
G
H
I
J
K
L

Y
Z
1
2
3
4
5
6
7
8
9
0

10.2. .

10 -

639


,
, .
- , . -
( 10.3.).
()
(-
) . ,
, (-
), -
- .
, : .
t ( 10.2.),
- . , ,
- ( 10.4.1.) ( 10.4.2.), (
10.4.5.) .

,
( - , ), , .
() . , ,
, .
,
. - LZ77, LZ78 ( 10.6.5.) LZW
( 10.6.8.).

, .
()
. ,
100% . ,
, . -
JPEG ( , 10.7.2.), MP3 () MPEG (,
10.7.3.).

, . ,
. , (
10.7.5.).

, . . ( 10.5.)

10 -

640

10.3.
10.3.1.
(. null suppression) - . , IBM 3780
.

, , , (
) , .
. -
. 0,
1, ..., 255. , 0 . 1 , : 1, 2, ..., 256. :
12 17 86 93 0 0 1 2 0 0 0 0 0 19 20 0 8 3 12 0 0 0 6

:
12 17 86 93 0 1 1 2 0 4 19 20 0 0 8 3 12 0 2 6

256.

. , 1000 ,
10.3.1.

255

255

255

231

10.3.1. 1000 .
- -
.
, , ,
. .
, ,
. , , .
, . ,
() .
, , .
.
, a ,
. , ,
.
SI ( . shift in) SO ( . shift out),
10.3.1.
SI

SO

10.3.1. .

10 -

641

4(5) . -,
( 10.3.9.), ,
, escape.
.
?
. , . .
IBM 3780 BISYNC, ,
30-50%. [Held-1991]
. ,
, .
, . ,
, . ,
.
, (
) ,
. tab ( 9 ASCII
. American Standard Code for Information Interchange)
8 . .
, 5 , 10, 20,
.
: , tab - .
, .
tab, , . ,
10 . tab , . . 10,
. , , . .
20 .. tab :
0,1,...,9. .
,
.
:
1. , .
2. escape ,
.
3. SI SO.
4. .

10.3.2.
, - ( , .) .
0 1, ( 1)
( 0) . (. bit
mapping) . ,
,
.
. :

10 -

642
0 13 0 0 89 0 37 0

, 0 5/8. , , -
2. . 2, 5 7.
: 01001010. , ( 7410 )
:
74 13 89 37

50%, 8 4
( 8, 1 .).
. , -? 10.3.2.
8
. , - 12,5%
, .

%

0
0

1
12,5

2
25

3
37,5

4
50

5
62,5

6
75

7
87,5

8
100

0,888

1,000

1,143

1,334

1,600

2,000

2,667

4,000

8,000

10.3.2. .

. p
, n . np. n(1p) + n/8:
np n/8,
. ( n/8 n/8). :

n
n1 p
8
10.3.2.
n = 8, 6 .
: p = 6/8 = 0,75. : n(1p) + n/8 = 8(10,75) +
8/8 =3. : 8/3 = 2,667.
,
: , , . ,

. , . , , ,

. ,
, . (
10.3.9.), -.

10 -

643

? , , . ,
. ..
.
:
1. .
2. ?
3. (
0)? - ?
4. ,
, , , ?
5. ( 10.3.1.).
? ?

10.3.3.
(. halfbyte packing)
.
. , EBCDIC ( . Extended Binary-Coded Decimal
Interchange Code) 0, 1, ..., 9 ,
10.3.3.

0
1
2
3
4
5
6
7
8
9

0000 0000
0000 0001
0000 0010
0000 0011
0000 0100
0000 0101
0000 0110
0000 0111
0000 1000
0000 1001

16-
EBCDIC
F0
F1
F2
F3
F4
F5
F6
F7
F8
F9


EBCDIC
1111 0000
1111 0001
1111 0010
1111 0011
1111 0100
1111 0101
1111 0110
1111 0111
1111 1000
1111 1001

10.3.3. EBCDIC.
. . , .
: 11112. , 38 001110002. ,
ASCII. 00112.
? , ,
50%. , , .
, , , -. , , , . . -
, 10.3.3.

10 -

644

n1

...

10.3.3. : .
. , , . n , . : , ! n . ,
. 4- .
, ,
(
10.3.3.). : ,
? : ,
11112.

...

n1

10.3.3. : .
3 2
. 4
( ), 5 (
) 6 ( )
, 3 ( ), 4 (
), 5 ( )
, . 4-
15. 0, 1, 2 3 .
, 0 4.
37 (?). ,
, 255,
5, 519 (?).
. n (n 5). 8n.
16 + 4.n/2 .
:
8n

n
16 4
2
12 + 4 .
[n/2], n 4. :
8n

n
12 4
2
T 10.3.3. .

16

10 -

645

2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
24
32
40
48
56
64
72
80
88
96
104
112
120

24
24
32
32
40
40
48
48
56
56
64
64
72
72

00.00%
20.00%
16.66%
28.00%
25.00%
33.33%
30.00%
36.36%
33.33%
38.46%
35.71%
40.00%

10.3.3.
.
- .
, , .
, 4 ( ) 16. , 10. 6
( 5, ,
.). , -: 256
100.
, , .

: $, %, +, , *, /, =, (, ), , . ,
,
. , , ,
. .
, 16
, . T 10.3.3.
-
.

0
1
2
3
4
5
6
7
8
9
+

0000 0000
0000 0001
0000 0010
0000 0011
0000 0100
0000 0101
0000 0110
0000 0111
0000 1000
0000 1001

ASCII

0011 0000
0011 0001
0011 0010
0011 0011
0011 0100
0011 0101
0011 0110
0011 0111
0011 1000
0011 1001
0010 1011

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010

10 -

$
,
.
*

646

0010 1101
0010 0100
0010 1100
0010 1110
0010 1010

1011
1100
1101
1110
1111

10.3.3. .
:
1. 156 256-
.
2. ( 10.3.1.)
( 10.3.2.) .

10.3.4.

- 7- ASCII , -
, .
00100100 10100100 , $.
, .
, ,
? : - 1, 0. , ( 10.3.2.).
, . .
1, ,
( 10.3.3.). 6
6- , 6- , 64
. , 4 ,
.
5 , 32 .
:
1. .
2. .
3. , 8 .

10.3.5.

E_
_T
TH
_A
S_
RE

328
292
249
244
217
200



26,89
23,94
20,41
20,00
17,79
16,40

10 -
IN
HE
ER
_I
_O
N_
ES
_B
ON
T_
TI
AN
D_
AT
TE
_C
_S
OR
R_

647
197
183
171
156
153
152
148
141
140
137
137
133
133
119
114
113
113
112
109

16,15
15,00
14,02
12,79
12,54
12,46
12,13
11,56
11,48
11,23
11,23
10,90
10,90
9,76
9,35
9,26
9,26
9,18
8,94

10.3.5. - .
(. diatomic encoding) . , ,
. 50% , -
. ,
. - - .
. , ,
.
, ,
- .
.
.
, ,
. 10.3.5. (
), 12 198 . [Jewell-1976]

- .
, .
, ,
. , -
.
:
1. -
10.3.5.
2. - :

10 -

648

;
;
, , , , Java.
3. .
4.
?
5. ,
.
6. .
7. , 3 ( ) ? ?

10.3.6.

( 10.3.5.). , .
50% .
,
. ,
. , .
: , , , , . :
the, for, of . , -
, -, . .
.
- , ( ).
, .
10.3.6.
.
- .
GWBasic. , /1 IBM,
, ( -), .


FOR, GOTO, GOSUB, IF, INPUT, LET, NEXT, PRINT, REM,
THEN
do, else, for, if, int, void, while
DO, FORMAT, READ, WRITE
if, else, for, function, procedure, repeat, then,
until, write

10.3.6. .
:
1. -
. , .
2. ,
?
3. .

10 -

649

10.3.7.

, .
, . ,
:
1991 1992 1990 1992 1995 1994 1991

, 11 (211 = 2048).
,
. :
1991 1 2 2 3 1 0 3

10.3.7.
.

10.3.7. .

, , ,
3 . -, (. delta encoding)
(a1, a2,..., an)
(a1, a2a1, ..., ana1). ""
, .
10.3.7. 10.3.7. .
. (), . ,
.
, . .
. ,
, 30 , , , . . " ".
. -. ,
1728 . .
" " (
^ ), . :
00111001 00001101 10110111 --> i

10100001 01100001 01110110 --> i+1


10011000 01101100 11000001 -->

, :
1 0 = 0 1 = 1
0 0 = 1 1 = 0

10 -

650

. , ,
. - ,
- ( 10.3.1.).
, "0" "1". - () . - , ,
. -
. ( 10.4.2.)
. ,
1780 96 , 1 410 048
. 42 33 600 bps (
. Bits Per Second), 4 .
sccs
UNIX, ,
.
,
.
,
, . . .
:
1. :
) ;
) .
2.
.

10.3.8. .

- .
,
, - .
, . .
,
. - ,
, . .
.
,
.
.
.
LPC ( . Linear Predictive Code)
. : 1000 ,
- .
. [Smith-1998]
? ,
, .
X, x1, x2, , xn
P(x1), P(x2), , P(xn) :

10 -

651
n

EX xi Pxi
i 1

X X . ,
0 1 .
, 10000 , 5037
. 1, . .
, 5037/10000 = 0,5037.
: .
1, 2, 3, 4, 5 6, . 2. P(x = 2) = 1/6 ( / _ ).
? 3 : 2, 4 6.
6, P(x ) = 3/6 = 1/2.

. - , i P(i) = 1/6, 1 i 6.
:
EX = 1.P(1) + 2.P(2) + 3.P(3) + 4.P(4) + 5.P(5) + 6.P(6)
EX = 1.(1/6) + 2.(1/6) + 3.(1/6) + 4.(1/6) + 5.(1/6) + 6.(1/6)
EX = (1 + 2 + 3 + 4 + 5 + 6) / 6 = 3,5
, . .
, 3,5. , : ,
3,5.
. , 200 .
74 , 31 , 10 , 2 1
. ?
: 118. k- P(k) =
#k/118, k{1, 2, 3, 5, 24}. #k k.
EX = 1.(74/118) + 2.(31/118) + 3.(3/118) + 5.(2/118) + 1.(24/118) = 200/118 1,694 /
: ?
-: , , "", . .
. ,
( ) ,
EX = {x1, x2, ..., xk }, EX = {x1, x2, ..., xk , xk+1}, . .
. :

EX

(n 1) EX _ _
n

.
:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
const char *message="LLLLLLALABALANICAAAABABABBABABABABAAABABALLLLAABB";
/* LPC */

10 -

652

void LPCencode(int *code, const char *msg)


{ double exp;
unsigned n;
if ('\0' == *msg) return; /* */
for (exp = *code = *msg++, n = 1; '\0' != *msg; n++, msg++) {
code[n] = (int) ceil(exp-*msg);
exp = (exp*n + (unsigned char)*msg)/(n+1);
}
}
/* LPC */
void LPCdecode(char *msg, const int *code, const unsigned n)
{ double exp;
unsigned i;
for (exp = *msg++ = *code, i = 1; i < n; i++, msg++) {
*msg = (char)ceil(exp - code[i]);
exp = (exp*i + (unsigned char) *msg) / (i+1);
}
*msg = '\0';
}
void print(const int *code, const unsigned n)
{ unsigned i;
for (i = 0; i < n; i++)
printf("%4d", code[i]);
}
int main(void) {
int coded[MAX];
/* */
char decoded[MAX]; /* */
printf(" :\n%s\n", message);
LPCencode(coded, message);
printf("\n :\n");
print(coded, strlen(message));
LPCdecode(decoded, coded, strlen(message));
printf("\n :\n%s", decoded);
return 0;
}

lpc.c
:
:
LLLLLLALABALANICAAAABABABBABABABABAAABABALLLLAABB
:
76
0
0
0
0
0 11 -1 10
8
8 -3
5
6
5
5
4
4
5
4
5
4
4
3
4 -8 -7 -7 -7
4
4
3
3
:
LLLLLLALABALANICAAAABABABBABABABABAAABABALLLLAABB

8
4

-6
3

0
4

6
4

7
4

7
3

7
4

6
3

,
. ,
x 70%, x
3%,
.
( 10.4.) ( 10.5.)
.

10 -

653

?
. . , , .
- ( -
), - :
. ,
( ) .
( 10.3.9.) (
10.3.2.).
:
1.
, ,
. ?
2. .

-.
. ?
3. 10.3.7.

10.3.9.
(. run-length encoding)
. ( 10.3.1.) ,
, - . , -
, :
BBBBBBBCCCCCAAAAAAAAAAAAACCCABABBCCAAAAAAAAAAAAAAAAAAAA

(*)

, .
,
- , , . ,
- .
:
7B5C13A3CABABB2C20A

,
, ,
. , ,
.
, , . .
, .
, , 2, ,
. , ,
.
, , .
( ):
000000001111111000000
000000011111111110000
000001111111111111000
000001111111111111000

8
7
5
5

7 6
10 4
13 3
13 3

10 -

654
000000011111111110000
000000001111111000000

7 10 4
8 7 6

-
(. bitmap). : 0 , 1
.
,
.
, ( bitmap), , .
2
, . ,
10.3.1., 8
.
4%.
- , . - , ,
,
. , , .
.
, .
, , , .
, .
escape .
,
, . ( , 10.3.1.
, SI SO.)
, 26-
(- ). escape
, .
: escape .
escape . ,
XY (_,).
Y X . 7 G, 5 E, 13
M, 20 T. (*) ( Z
escape ):
ZGBZECZMACCCABABBCCZTA

escape 3 ,
4. ,
Z? , , ,
, .
, , . escape 0, . , , Z, , .
. escape .
, .
. [Sedgewick-1990]

10 -

655

:
1. Z escape
, ZZ? ZZZ? ZZZZ?
2. :
ZAZZZZZSDHDGSDGHGZGZGZHJGG, Z escape .
3. , k . k?
4. (
10.3.1.).
5. ,
?

10.3.10. : PackBits

PackBits, Macintosh.
( 8 ) 9 .
.
, . . 0 255,
256 255 . , 0, . .
, 8 . ,
1 ( ), .
, 5,5,5,5,5,5,5,5 (5,7).
,
: 5. ,
(8) (5).
PackBits 9- .
, . .
8 .
,
1/9.
9- , .
. , ASCII
, 128 255 (
) ASCII . ,
, - 127,
PackBits. [Smith-1998]
,
. ,
, -.
:
1. PackBits .
2. PackBits 10.3.4.

10 -

656

10.4.
10.4.1. -

: , . , ,

.
. , , .
, Bell Labs M. ,
MIT, .

. (-
, .)
:
1. .
2. - - .
3. .
, . , , -. , , . ,
( ) .
() ,
,
. , , , .
ASCII.

12,68%
1,08%
4,77%
1,01%
3,33%

9,64%
0,76%
2,21%
8,54%
0,48%

3,43%
3,04%
3,30%
8,17%
9,05%

2,50%
4,67%
4,41%
7,80%
1,44%

0,78%
0,35%
0,87%
1,62%
0,18%

0,60%
1,56%
0,02%
0,10%
1,61%

10.4.1. .

. , , ( 27 ), 5- ,
8- ASCII, 37,5%. 5
25 = 32 , 27 .

. , -
- , . - , . 10.4.1.,
,
[-1996].
, .
.

10 -

657


,
. .
: a 01, b 11, c 0111 : 01110111.
, : abab, abc, cab cc.
: ?
, - . ,
, ()
. , .
. , : a 01, b 00, c 0111. ,
, (a c). , ,
. [-1996]

f
c
d
e
a
g
b

0,25
0,20
0,15
0,15
0,10
0,10
0,05

1
1
0
0
0
0
0

1
0
1
1
0
0
0

1
0
1
0
0

1
0

10.4.1. - : (a:0,1), (b:0,05), (c:0,20), (d:0,15),


(e:0,15), (f:0,25) (g:0,10).
.
? ,

( [-1996]). , . , ,
, .
, ,
, .
() (. . ) . -
, .
-
1. .
2. () .
3. 0, 1 .
4. , , 2.
.
: (a: 0,1), (b: 0,05), (c: 0,20),
(d: 0,15), (e: 0,15), (f: 0,25) (g: 0,10). ,
: f, c, d, e, a, g, b. .
10.4.1.
: (a: 001), (b: 0000), (c: 10), (d: 011), (e: 010), (f: 11) (g: 0001). ,
, -

10 -

658

: , (
), , . .
.
. .
0

fcdeagb
1,00

fc
0,45
0
f
0,25

deagb
0,55
0

1
c
0,20

de
0,30
0
d
0,15

agb
0,25
1
e
0,15

0
a
0,10
0
a
0,10

1
gb
0,15
1
gb
0,15

10.4.1. - : (a:0,1), (b:0,05), (c:0,20), (d:0,15),


(e:0,15), (f:0,25) (g:0,10).
?
, .
, , , . , , 0,
1. 0 1,
, , 10.4.1. ,
( -). ,
, , .
? : 0,
, 1 .
, , .

a
b
c
d
e
f

0,20
0,20
0,20
0,15
0,15
0,10

1
1
0
0
0
0

1
0
1
1
0
0

1
0
1
0

10.4.1. - : (a:0,20), (b:0,20), (c:0,20), (d:0,15),


(e:0,15), (f:0,10). 1.
, -
. .
,
. : (a: 0,20), (b: 0,20), (c: 0,20), (d: 0,15), (e: 0,15), (f:
0,10). 3 -: 10.4.1., 10.4.1. 10.4.1.

10 -
a
b
c
d
e
f

659
0,20
0,20
0,20
0,15
0,15
0,10

1
1
1
0
0
0

1
0
0
1
0
0

1
0
1
0

10.4.1. - : (a:0,20), (b:0,20), (c:0,20), (d:0,15),


(e:0,15), (f:0,10). 2.

a
b
c
d
e
f

0,20
0,20
0,20
0,15
0,15
0,10

1
1
1
0
0
0

1
1
0
1
0
0

1
0

1
0

10.4.1. - : (a:0,20), (b:0,20), (c:0,20), (d:0,15),


(e:0,15), (f:0,10). 3.
li (1 i n) ai, pi . ,
. L.
:
n

L l i pi
i 1

, ( 10.3.8.)
. d()
. ai . lipid()
( ) , ai
. ,
( ) ([-1996]):
n

l p d d l p
i 1

i 1

d .L

,
. , , {a1, a2, ..., an}
a {p1, p2, ..., pn}, L , .
:
L1 = 2.0,20 + 2.0,20 + 3.0,20 + 3.0,15 + 3.0,15 + 3.0,10 = 2,33
L2 = 2.0,20 + 3.0,20 + 3.0,20 + 2.0,15 + 3.0,15 + 3.0,10 = 2,65
L3 = 3.0,20 + 3.0,20 + 2.0,20 + 2.0,15 + 3.0,15 + 3.0,10 = 2,65
, - ,
2,33 2,65 .
:
1. 10.4.1.

10 -

660

2. .
3. -?
4. -,
? ?
5. , , -, .
6. - ?
7. -.
8. - ,
?

10.4.2.
-, .

1. , ( ) .
2. - ,
.
3. , 2.
-. , . - - .
- , . . - .
,
-,
:
. " "
, , . . , . , , .
, .
- ,
, -, , ,
. , .
, ( 9.1.).
, , ,
.
:
afbabcdefacbabcdecde

: (a: 0,20), (b: 0,20), (c: 0,20), (d:


0,15), (e: 0,15), (f: 0,10) . ( 10.4.2.)

10 -

661

a
0,20

b
0,20

c
0,20
0

d
0,15

ab
0,40

e
0,15

f
0,10

cd
0,35

1
ef
0,25

0
cdef
0,60

1
abcdef
1,00

10.4.2. : (a:0,20), (b:0,20), (c:0,20), (d:0,15),


(e:0,15), (f:0,10).
, 10.4.2.
- ( 10.4.1.). ,
, -.
: a = 00, b = 01, c = 100, d = 101, e = 110 f = 111.
( - ):
00 111 01 00 01 100 101 110 111 00 100 01 00 01 100 101 110 100 101 110

8- ASCII 8.20 = 160 . , 6 , 3- , 3.20 = 60 .


52 , . . 52/20 = 2,6 .
? ,
n , ,
. (n2). , . . .
n. , n, - .
.
- .
,
MSG.
.
, , ( -
initModel()). . - , -.
forest[].
:
.
, . - :
void huffman(void)
{ /* */
while (forest___2_) {
findMins(i,j);
/* 1. - */
forest[i] = createNew(forest[i],forest[j]);/* 2. */
free(forest[j]);
/* 3. j- */
}
}

10 -

662

(
printTree()), (
writeCodes()) . ( findMins() -

):
#include <stdio.h>
#include <stdlib.h>
#define MAX 256
#define MSG "afbabcdefacbabcdecde"
struct tree {
char sym;
/* () */
unsigned freq;
/* */
struct tree *left, *right; /* */
};
struct {
unsigned weight;
struct tree *root;
} forest[MAX];

/* */
/* */
/* : */

unsigned treeCnt;

/* */

char code[MAX];

/* */

void initModel(char *msg)


{ char *c = msg;
unsigned freqs[MAX];
unsigned i;

/* */
/* */

/* */
for (i = 0; i < MAX; i++)
freqs[i] = 0;
while (*c)
freqs[(unsigned char) *c++]++;
/* */
for (treeCnt = i = 0; i < MAX; i++)
if (freqs[i]) {
forest[treeCnt].weight = freqs[i];
forest[treeCnt].root = (struct tree *) malloc(sizeof(struct tree));
forest[treeCnt].root->left = NULL;
forest[treeCnt].root->right = NULL;
forest[treeCnt].root->freq = freqs[i];
forest[treeCnt++].root->sym = i;
}
}
void findMins(unsigned *min,
unsigned *secondMin) /* - */
{ unsigned i;
if (forest[0].weight <= forest[1].weight) {
*min = 0;
*secondMin = 1;
}
else {
*min = 1;
*secondMin = 0;

10 -
}
for (i = 2; i < treeCnt; i++)
if (forest[i].weight < forest[*min].weight) {
*secondMin = *min;
*min = i;
}
else if (forest[i].weight < forest[*secondMin].weight)
*secondMin = i;
}
void huffman(void)
{ unsigned i,j;
struct tree *t;
while (treeCnt > 1) {
findMins(&i,&j); /* - */
/* - - */
t = (struct tree *) malloc(sizeof(*t));
t->left = forest[i].root;
t->right = forest[j].root;
t->freq = forest[i].weight += forest[j].weight;
forest[i].root = t;
/* j- . . */
forest[j] = forest[--treeCnt];
}
}
void printTree(struct tree *t, unsigned h) /* */
{ unsigned i;
if (t) {
printTree(t->left,h+1);
for (i = 0; i < h; i++)
printf("
");
printf("%4d",t->freq);
if (NULL == t->left)
printf(" %c",t->sym);
printf("\n");
printTree(t->right,h+1); }
}
void writeCodes(struct tree *t, unsigned index) /* */
{ if (t) {
code[index] = '0';
writeCodes(t->left,index+1);
if (NULL == t->left) {/* 0 2 */
code[index] = '\0';
printf("%c = %s\n",t->sym,code);
}
code[index] = '1';
writeCodes(t->right,index+1);
}
}
int main(void) {
initModel(MSG);
huffman();
printf(" %s:\n",MSG);

663

10 -

664

printTree(forest[0].root,0);
writeCodes(forest[0].root,0);
return 0;
}

huffman1.c
, forest[] .
-
.
:
afbabcdefacbabcdecde:
4 b
8
4 c
20
2 f
5
3 d
12
3 e
7
4 a
b = 00
c = 01
f = 100
d = 101
e = 110
a = 111

, , . ,
(i,j) . , ,
-- .
, .
, (<)
findMins() (),
huffman(). ( /* <-- */ ):
void findMins(unsigned *min,
unsigned *secondMin) /* - */
{ unsigned i;
if (forest[0].weight <= forest[1].weight) {
*min = 0;
*secondMin = 1;
}
else {
*min = 1;
*secondMin = 0;
}
for (i = 2; i < treeCnt; i++)
if (forest[i].weight <= forest[*min].weight) {
/* <-- */
*secondMin = *min;
*min = i;
}

10 -

665

else if (forest[i].weight <= forest[*secondMin].weight) /* <-- */


*secondMin = i;
}
void huffman(void)
{ unsigned i,j;
struct tree *t;
while (treeCnt > 1) {
findMins(&i,&j); /* - */
/* - - */
t = (struct tree *) malloc(sizeof(*t));
if (i < j) {
t->left = forest[i].root;
t->right = forest[j].root;
}
else {
t->right = forest[i].root;
t->left = forest[j].root;
}

/*
/*
/*
/*
/*
/*
/*
/*

<-<-<-<-<-<-<-<--

*/
*/
*/
*/
*/
*/
*/
*/

forest[i].weight += forest[j].weight;
forest[i].root = t;
/* j- . . */
forest[j] = forest[--treeCnt];
}
}

huffman2.c
,
t->freq. - ,
. printTree().

- huffman3.c.
:
afbabcdefacbabcdecde:
-- a
--- b
--- c
--- d
--- e
--- f
a
b
c
d
e
f

=
=
=
=
=
=

00
01
100
101
110
111

10 -

666

? - . (: 3.1.9.). , (log2 n). ,


(n) ,
(n.log2 n). , :
void huffman()
{ buildHeap();
/* */
/* 2 */
while (forest___2_) {
min1 = getMinAndRemoveFromHeap();/* 1. - */
min2 = getMinAndRemoveFromHeap();/* 2. - */
insert(createNew(min1,min2));/* 3. -> */
}
}

. ,
forest[] . /* <-- */.
#include <stdio.h>
#include <stdlib.h>
#define MAX 256
#define MSG "afbabcdefacbabcdecde"
struct tree {
/* <-- */
char sym;
/* */
struct tree *left, *right; /* */
};
struct CForest {
/* <-- */
unsigned weight;
/* */
struct tree *root;
/* */
} forest[MAX];
/* : */
unsigned treeCnt;
/* */
char code[MAX];
/* */
/***********************************************************/
/************** ***************/
/***********************************************************/
/* "" */
void siftUp(unsigned k)
/* <-- */
{ struct CForest save = forest[k]; /* */
unsigned parent = k/2;
/* "" */
while (parent >= 1) {
/* */
if (save.weight < forest[parent].weight) {
forest[k] = forest[parent];
k = parent;
}
parent /= 2;
}
forest[k] = save; /* */
}
/* "" */
void siftDown(void)
{ unsigned parent = 1,
/* "" */
child = 2;
/* "" */

/* <-- */

10 -

667

struct CForest save = forest[1]; /* */


while (child <= treeCnt) {
if (child+1 <= treeCnt) /* - */
if (forest[child+1].weight < forest[child].weight)
child++;
if (save.weight > forest[child].weight) {
/* */
forest[parent] = forest[child];
parent = child;
child *= 2;
}
else
break;
}
forest[parent] = save; /* */
}
void removeMin(void) /* */
{ forest[1] = forest[treeCnt--];
siftDown();
}

/* <-- */

/*********************************************/
/************* **************/
/*********************************************/
void initModel(char *msg) /* */
{ char *c = msg;
unsigned freqs[MAX]; /* */
unsigned i;
/* */
for (i = 0; i < MAX; i++)
freqs[i] = 0;
while (*c)
freqs[(unsigned char) *c++]++;
/* */
treeCnt = 0;
for (i = 0; i < MAX; i++)
if (freqs[i]) {
forest[++treeCnt].weight = freqs[i];
/* <-- */
forest[treeCnt].root = (struct tree *) malloc(sizeof(struct tree));
forest[treeCnt].root->left = NULL;
forest[treeCnt].root->right = NULL;
forest[treeCnt].root->sym = i;
siftUp(treeCnt);
/* <-- */
}
}
void huffman(void)
/* <-- */
{ struct CForest min1, min2;
while (treeCnt > 1) {
/* - */
min1 = forest[1];
removeMin();
min2 = forest[1];
removeMin();
/* - - */
forest[++treeCnt].root = (struct tree *) malloc(sizeof(struct tree));

10 -

668

forest[treeCnt].root->left = min1.root;
forest[treeCnt].root->right = min2.root;
forest[treeCnt].weight = min1.weight + min2.weight;
/* */
siftUp(treeCnt);
}
}
void printTree(struct tree *t, unsigned h)
/* , */
{ unsigned i;
if (NULL != t) {
printTree(t->left,h+1);
for (i = 0; i < h; i++)
printf("
");
printf(" -- ");
/* <-- */
if (NULL == t->left)
printf(" %c", t->sym);
printf("\n");
printTree(t->right,h+1);
}
}
void writeCodes(struct tree *t, unsigned index) /* */
{ if (NULL != t) {
code[index] = '0';
writeCodes(t->left,index+1);
if (NULL == t->left) { /* 0 2 */
code[index] = '\0';
printf("%c = %s\n",t->sym,code);
}
code[index] = '1';
writeCodes(t->right,index+1);
}
}
int main(void) {
initModel(MSG);
huffman();
printf(" %s:\n",MSG);
printTree(forest[1].root,0);
writeCodes(forest[1].root,0);
return 0;
}

/* <-- */
/* <-- */

huffman3.c
, ,
256,
ASCII. , n
(n2) (n.log2n). , .
, 256,
. , , .
(- ) .
, Unicode, 65536 . ,

10 -

669

. ,
, - (while,
for, if .), - . , , - . , , ,
. , ,
.
:
. . ( [TopTeam1997]). :
void writeTree(tree *t) { /* */
{
if (t != NULL)
/* t ? */
if (isLeaf(t)) {
/* t */
writeBit(0);
/* 0 */
writeSym(t->sym);
/* 8 ASCII */
}
else {
/* t */
writeBit(1);
/* 1 */
writeTree(t->left);
/* */
writeTree(t->right);
/* */
}
}

:
struct tree *readTree() { /* */
{ struct tree *l, *r, *p;
bit b;
if (1 == (b = readBit())) {
/* */
l = readTree();
/* */
r = readTree();
/* */
p = newNode(l,r); /* p l r */
return p;
/* p */
}
else {
/* */
sym = getSym();
/* 8 */
p = emptyNode(sym); /* , sym */
return p;
/* p */
}
}

- , n 10n
1 . , n , ,
n1 . (?) 8+1 = 9 , 1 .
, 9.n+1.(n1) = 10.n1 .
, :
.
,
. , ,
, .

10 -

670

. "",
- ( 10.4.1.). - ";".
.
, . ,
- , .
. . ,
.
,
. , .
, ( ),
.
.
: ? ,
, :
8 . ,
.
1.
, .
. ,
. - ,
8, :
,
: 0 7 3 .
- , , 20-25%.
, , . ,
. , -? , .
, -
, , , , (
DOS/Windows).
:
1. ? ?
2. , , , .
3. -.
4. , .
5. :

)
)
)
)

0,70
0,10
0,30
0,17

0,10
0,20
0,30
0,17

0,10
0,20
0,20
0,17

0,05
0,10
0,15
0,17

0,03
0,20
0,05
0,16

0,02
0,20
0,00
0,16

6. .
7. .

10 -

671

8. .
, ?
9. , 5 , ?
10. .

10.4.3.
-
, n- . , . . ,
( 0, 1 2),
. ? ,
, , .
, . . 3 . ,
, . : , . ?
- ,
.
1.
()
, 2. , . , , .
. , ,
. ,
. , n, - , n.
- .
? :
. , 0,
1, 2. ,
, 10.4.3.
: a = 0, b = 10, c = 11, d = 12, e = 20 f = 21.
( )
. (
):
L = 0,20.1 + 0,20.2 + 0,20.2 + 0,15.2 + 0,15.2 + 0,10.2 = 1,8
, 1,8 . 2,6 . , .
, !

10 -

672

a
0,20

b
0,20

c
0,20
0

d
0,15

e
0,15

f
0,10

bcd
0,35

1
ef
0,25

1
2
abcdef
0,60

10.4.3. : (a:0,20), (b:0,20), (c:0,20),


(d:0,15), (e:0,15), (f:0,10).
k- ? , . k- -
. , 3- . s- - , s
2, 3, ..., k, k1 ns. , ,
, . , 0,
1, 2, ..., k- (k1).
:
1. ,
- ?
2.
?
3.
? ? ?

10.4.4. K
- - ( 10.4.1.) ( 10.4.2.)
: , , , . , , - . ,
,
. .
, -
? ? , ASCII, . . , . : (a: 0,4), (b: 0,2), (c: 0,2),
(d: 0,15) (e: 0,05). 3 . , , : (a = 11), (b = 10), (c = 01), (d =
001), (e = 000). :
L = 2.0,4 + 2.0,2 + 2.0,2 + 3.0,15 + 3.0,05 = 2,2

10 -

673

,
, ? (. comma code). , .
. ? : . 1, 01,
001, 0001 .. ,
- . -
.
: a = 1, b = 01, c = 001, d = 0001, e = 00001. :
L = 1.0,4 + 2.0,2 + 3.0,2 + 4.0,15 + 5.0,05 = 2,25
, .
:
1. ?
2. .
3. .

10.4.5.
,
. . , - 20%
25%. , -
, .
-
: . , .
, -. - (
10.3.7.) - -, . . . ,
90% . 0,
1. , . . . , 0,15 , . . -. , ,
. ?
. ,
. 8 256 ,
- .
, . , :
, (
). , -
, .
?
. ,
, -
, .
- 0 1 .

10 -

674

? , :
"".
, ,
. , ,
,
[0;1]. :
1) , . . [l;r);
2) ;
3) [0;1);
4) ,
.


20%
10%
20%
10%
10%
10%
20%

0,00
0,20
0,30
0,50
0,60
0,70
0,80

0,20
0,30
0,50
0,60
0,70
0,80
1,00

10.4.5. .
T 10.4.5. .
, , . ,
7! = 5040 . ,
. - ,
.


0,000000000
0,000000000
0,140000000
0,146000000
0,149200000
0,149680000
0,149696000
0,149702400
0,149702880
0,149703040
0,149703040


1,000000000
0,200000000
0,160000000
0,150000000
0,150000000
0,149760000
0,149704000
0,149704000
0,149703200
0,149703072
0,149703046

10.4.5. : .
? [0,00; 1,00), .
[0,00; 0,20).
. . [0,70;
0,80). 70% 80% [0,00;
0,20). [0,14; 0,16). , [0,30;
0,50). [0,14; 0,16) 30%, 50%,
[0,146; 0,150). , [0,80; 1,00).
[0,1492; 0,1500). T
10.4.5. -.

10 -

675

, : [0,149703040; 0,149703046). .
, ,
. , [0,149703040; 0,149703046)
.
:
l = 0.0; r = 1.0;
while (getSymbol(ch)) {
range = r - l;
l = l + range * low_range(ch);
r = l + range * high_range(ch);
}
output(l);

? . , ,
. . , .
, .
0 1, .
(. .
), .
, .. : ? ,
,
. : , ,
. - . T
10.4.5. .

0.149703040
0.748515200
0.485152000
0.925760000
0.628800000
0.288000000
0.880000000
0.400000000
0.500000000

0,00
0,70
0,30
0,80
0,60
0,20
0,80
0,30
0,50

0,20
0,80
0,50
1,00
0,70
0,30
1,00
0,50
0,60

0.000000001

0,00

0,20

10.4.5. .
:
for (i = 0; i < messageLen; i++) {
symbol = getSymbol(msg);
writeOut(symbol);
range = high_range(symbol) - low_range(symbol);
msg -= low_range(symbol);
msg /= range;
}

10 -

676

, -
90% .
- - .
"" 10.4.5.


0,0
0,0
0,9


1,0
0,9
1,0

10.4.5. "".

0,900000000
0,900000000
0,900000000
0,900000000
0,900000000
0,900000000
0,900000000
0,900000000
0,900000000
0,900000000

1,000000000
0,990000000
0,981000000
0,972900000
0,965610000
0,959049000
0,953144100
0,947829690
0,943046721
0,938742049

0,9!
, , 10 - ! , . 100000
16382/16383
1/16383, ! ,
- 12501 . ,
. ,
, - .
, . -
, , - .
, 510%.
:
#include <stdio.h>
#include <string.h>
#define SHOW_MORE
#define MESSAGE ""
#define MAX 256
struct {
double low, high;
} sym[MAX];
unsigned freq[MAX];
void getStatistics(char *mesg) /* */
{ unsigned i;
for (i = 0; i < MAX; i++)
freq[i] = 0;

10 -
while ('\0' != *mesg)
freq[(unsigned char) *mesg++]++;
}
void buildModel(char *mesg) /* */
{ unsigned i, cnt, n;
for (n = strlen(mesg), cnt = i = 0; i < MAX; i++) {
sym[i].low = (double) cnt/n;
cnt += freq[i];
sym[i].high = (double) cnt/n;
}
}
void printModel(void)
{ unsigned i;
printf("\n
");
printf("\n

");
for (i = 0; i < MAX; i++)
if (freq[i])
printf("\n%4c
%1.4f %1.4f", i,sym[i].low,sym[i].high);
}
double arithmeticEncode(char *mesg) /* */
{ double range, low, high;
low = 0.0, high = 1.0;
while ('\0' != *mesg) {
range = high - low;
high = low + range * sym[(unsigned char) *mesg].high;
low = low + range * sym[(unsigned char) *mesg].low;
#ifdef SHOW_MORE
printf("\n%c
%1.9f %1.9f",*mesg,low,high);
#endif
*mesg++;
}
return low;
}
char getSymbol(double encMsg)
{ unsigned i;
for (i = 0; i < MAX; i++)
if (sym[i].low <= encMsg && sym[i].high > encMsg)
break;
return (char) i;
}
void arithmeticDecode(double msg, unsigned msgLen) /* */
{ double range;
unsigned char ch, i;
for (i = 0; i < msgLen; i++) {
ch = (unsigned char) getSymbol(msg);
#ifdef SHOW_MORE
printf("\n%c
%1.9f",ch,msg);
#else
putc(ch,stdout);
#endif
range = sym[ch].high - sym[ch].low;
msg -= sym[ch].low;
msg /= range;
}
}

677

10 -

678

int main(void) {
double code;
printf("\n\n : %s",MESSAGE);
getStatistics(MESSAGE);
buildModel(MESSAGE);
#ifdef SHOW_MORE
printModel();
printf("\n <<ENTER>>"); getchar();
#endif
code = arithmeticEncode(MESSAGE);
printf("\n : %1.8f",code);
printf("\n: ");
arithmeticDecode(code,strlen(MESSAGE));
return 0;
}

arithmet.c
:
:

0.0000 0.2000

0.2000 0.3000

0.3000 0.5000

0.5000 0.6000

0.6000 0.7000

0.7000 0.8000

0.8000 1.0000
<<ENTER>>

0.000000000 0.200000000

0.140000000 0.160000000

0.146000000 0.150000000

0.149200000 0.150000000

0.149680000 0.149760000

0.149696000 0.149704000

0.149702400 0.149704000

0.149702880 0.149703200

0.149703040 0.149703072

0.149703040 0.149703046
: 0.14970304
:

0.149703040

0.748515200

0.485152000

0.925760000

0.628800000

0.288000000

0.880000000

0.400000000

0.500000000

0.000000001



. , , , [-1998], .

10 -

679

, -
. ,
,
. , ,
, , .
15- ,
, , ,
.
80 , . . 10 ,
, ,
.
, . 80-
IEEE ,
. -
.
, . ,
.
: - -
, -.
- , , ,
, 16 32-
. - , .
. 0 1. , , 1
0,99999999 . : [0;0,99999). , . ?
: 0 1, . .
xxxx , ,
0, . . 0,xxxx. ,
, 0 99999. , ,
1 = 0,99999, 00000
99999. :
, 1. , -
"" 10.4.5.

20%
10%
20%
10%
10%
10%
20%

00000
20000
30000
50000
60000
70000
80000

19999
29999
49999
59999
69999
79999
99999

10.4.5. "".
, ,
1. :
, . -

10 -

680

, ,
. k ,
. ,
, .
, ,
, .
10, 2.
, p p 0
.
<<. ,
( ),
0, 9 (
1).
"". ,
, ( 10.4.5.).
, .
. , -
. ,
, .
39999 40000 , .
,
, !
? , ,
. ? ! . ,
, 0 9 . ,
. ( 4 5) " "
, , ,
. , ,
. , -
, . ,
, .
, ,
0 9 , - -
- .
/


00000
00000
14000
40000
46000
60000
92000
20000
68000
69600
70240
02400
24000

99999
19999
15999
59999
49999
99999
99999
99999
75999
70399
70399
03999
39999

100000
20000
2000
20000
4000
40000
8000
80000
8000
800
160
1600
16000


0,
0,
0,
0,1
0,1
0,14
0,14
0,149
0,149
0,149
0,149
0,1497
0,14970

10 -

681
28800
30400
04000
40000
40000
00000
00000

31999
30719
07199
71999
45999
19999
99999

3200
320
3200
32000
2000
20000
100000

0,14970
0,14970
0,149703
0,1497030
0,1497030
0,14970304
0,149703041

10.4.5. : .
. ,
, ,
. . -
.
: ,
. ,
1. [-1998].
:
1. ( 10.4.2.).
- ? ?
2. .

10.5.
- . , , ,
.

. ,
- , - .
. ,
, . ,
, , .
-
,
. .
,
, .
,
. -
,
.

.
, ,
.
.

10 -

682

. , ,
.
, , .
, - .
, .
- - . :
bdaacacbab, 10.5., 10.5., 10.5., 10.5. 10.5.
,
. , ,
. , .
, . , , , : , ,
..
, .
, , -
( ). , , .

, 2 .
. ,
2,
, .
- 2.

a
b
c
d

0
0
0
0

0
10
110
111

10.5. bdaacacbab: .

b
a
c
d

1
0
0
0

0
10
110
111

10.5. bdaacacbab: b, 10.

d
b
c
a

1
1
0
0

0
10
110
111

10.5. bdaacacbab: d, 111.

10 -

683
d
b
c

1
1
0

10
110
111

10.5. bdaacacbab: a, 111.

a
d
b
c

2
1
1
0

0
10
110
111

10.5. bdaacacbab: a, 10.


:
1. .
2. .
3. .
?
4. ,
, ?

10.5.1.
, 10.4.2., ,
. ,
() . :

, , . - ,
- ,
. , . , ,
. . - :
. ,
, .
: 1)
? 2) ?
, .
, .

. :
initModel();
while(!eof(input)) {

10 -

684

sym = getSymbol(input);
encSym = encode(sym);
writeOut(output, encSym);
updateModel(sym);
}

:
initModel();
while(!eof(input)) {
sym = getSymbol(input);
decSym = decode(sym);
writeOut(output, decSym);
updateModel(sym);
}

: initModel() updateModel().
. - - .
.
, , , . ,
. ,
, . .
,
, . , .
- ? . :
- .
- (
.). ..
. .
- , .
.
- , 3 4 . .
, . . - , 2n1
.
,
. ,
. . . .
.
, .
, .
. , .
, - .
. ,
.
-
. , ,

10 -

685

, ,
.
, . . ,
. . : , , ,
- , . ,
, . ( , , , , ,
.)
, ,
. :
? - . ,
, , . .
() . , , . ,
.
, ,
, . ,
.
- . : , ,
?
0, escape. l , escape, l. escape, , , .

. . ,
. , unsigned, , , . .
. . 2, . , . ,
. .
, , , ,
2 . ,
, ,
. .
, , - , 2, : . 2
. , 1/2,
, -.
.

10 -

686

:
1. .
2. 10.5. , . - ?
3. escape .

10.5.2.
,
. ,
.
DOS/Windows. , ASCII
13 10 . ASCII 10
15%. 13, 10
100%! (, .)
, () . -
, , .

(- ), .
256 , ,
. . ,
, .
, 256 , 256 ,
256 . . . 65536 (. ) . i- , , ASCII i. 10 13- ( 0)
1 ( 10 13). ,
- . , 2, . .
, 16777216 65536
256 . , , . - .
-: - ( )
, .
,
,
. . , ,
. -
,
. : . - . ,
:
.
- , ,
16777216 , 256 .
: (
) . , . . -

10 -

687

. ,

, , . (,
, . ;)))
,
, ,
- : , . , . ,
, .
, 1 .
escape , , , - 1. , escape . , (1)- ,
, . .
. ,
, . . .
escape . , escape - .
, escape , - . escape , , . ,
escape .
.
"" , . .
. escape . ( [-1998]) escape, : , .
- , - . escape
:
= (256-#_) * #_/(256*__)
( < 1) = 1

. , ,
. , . . escape .
- : , . :
. .
0 ( ). . , , NULL.
: . . (, ).
.
, . , ,
- , , . , . . () .
, escape -

10 -

688

, . . .
. ,
-.
struct CRow { /* : */
char symbol;
/* */
unsigned cnt;
/* */
struct CContextTable *nextLevel; /* */
};
struct CContextTable { /* : */
unsigned char cnt;
/* */
struct CRow *rows;
/* */
struct CContextTable *parentTable; /* */
};

:
1. .
2. -
?
3.
- ( ).
4. .

10.5.3. : MNP-5
- .
: , ,
, , , - ,
.
, , MNP ( . Microcom Networking Protocol). , Microcom Inc.
. ,
, . - MNP 5. -,
.
( 10.3.9.). ,
. , ,
. . ,
, 0. 250,
.

. 8 ,
ASCII , .
. - ,
, . ,
, 256 , 128 0,
. . 7-
. , ,
ASCII
. , -

10 -

689

. 10523+5, 10523 + 00005. ,


:
1) (00000000) ;
2) , .
, MNP-5 ,
. , ,
, ,
. , - - , 10.5.3.
, , 10.5.3.,
- . . MNP-5
.
, 00000000 - , 4 . , -
, - . -
, ,
., .
, ,
-. , (
7/8) 8.
, . . 8 ,
. .
, MNP-5 -:
11111111111. .
ASCII

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

00000000
00000001
00000010
00000011
00000100
00000101
00000110
00000111
00001000
00001001
00001010
00001011
00001100
00001101
00001110
00001111
00010000
00010001
00010010
00010011
00010100
00010101

000
000
001
001
010
010
010
010
011
011
011
011
011
011
011
011
100
100
100
100
100
100

0
1
0
1
00
01
10
11
000
001
010
011
100
101
110
111
0000
0001
0010
0011
0100
0101

10 -
22
23
24
25
26
27
28
29
30
31
32
33
...
247
248
249
250
251
252
253
254
255

690
00010110
00010111
00011000
00011001
00011010
00011011
00011100
00011101
00011110
00011111
00100000
00100001
...
11110111
11111000
11111001
11111010
11111011
11111100
11111101
11111110
11111111

100
100
100
100
100
100
100
100
100
100
101
101
...
111
111
111
111
111
111
111
111
111

0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
00000
00001
...
1110111
1111000
1111001
1111010
1111011
1111100
1111101
1111110
11111110

10.5.3. MNP-5. .
? ,
, 50%, - , ASCII , 4 , . . -.
: 32
, - 8, 224
. , ,
. 15- -
50% . 15% 256 = 38,4. . . 38,4 50%
. 64 .

3:2 2:1. , MNP-5,
14400 19200 bps 9600 bps.
:
1. . ?
2. 10.5.3.
?

10.6.
, . .
, . ,
. -

10 -

691

, . . . ? , , . ,
. : , , , - - .
2n, n .
.
- . , . , ,
. ,
. ,
( ) ,
.
, . -
. 0, .
, , .
-
. , ,
.
, .
, :
.
:
1.
.
2. ( ) .
3. ?

10.6.1.
, : a b, a
90%. : aa, ab, ba
bb. 10.6.1.
,
? ( 10.4.2.) . , a b, . . ,
. ?

aa
0,81

ab
0,09

ba
0,09

bb
0,01

10.6.1.
{a,b} 90% a.
10.6.1. ,
.
4 ( ,
2), : aa = 0, ab = 10, ba = 110, bb = 111.
, :

10 -

692
L2 = 1.0,81 + 2.0,09 + 3.0,09 + 3.0,01 = 1,29

, (a
b), 2. 0,645 /,
.

aaa
0,729
0

aab
0,081
100

aba
0,081
101

baa
0,081
110

abb
0,009
11100

bab
0,009
11101

bba
0,009
11110

bbb
0,001
11111

10.6.1. {a,b}
90% a.
.
10.6.1. , ,
, L3 = 1,598. 3, ,
0,533 /. , -
. ? ? ,

?

aa
0,64
0

ab
0,16
10

ba
0,16
110

bb
0,04
111

10.6.1. {a,b}
80% a.
, , . a 80%.
,
, . 10.6.1. 10.6.1.
. , .
. : L2 = 1,56
L3 = 2,184. 2 3, 0,78 0,728 /. ,
,
. , , , . , : , ( 10.3.9.).

aaa
0,512
0

aab
0,128
100

aba
0,128
101

baa
0,128
110

abb
0,032
11100

bab
0,032
11101

bba
0,032
11110

bbb
0,008
11111

10.6.1. {a,b}
80% a.
, ? , 1940 .
. ,
. , 100%
, .

10 -

693

, , .
, , .
.
, , -
, - . [Admek-1991, Held-1991, Wayner-1996]
, ,
( ), ( ). ,
.
, , .
.
. ,
, .
, ,
. ,
H(p1,p2,...,pn)
p1,p2,...,pn , :
: H 0;
:
;
: H(p1,...,pi,...,pj,...,pn) = H(p1,...,pj,...,pi,...,pn); 1 i, j n
:
p1
p2

H ( p1 , p2 ,..., pn ) H ( p1 p2 , p3 ,..., pn ) ( p1 p2 ).H


,
p

p
p
2
1 p2
1
n
n1 2 .
. .
, . , , . , ,
. .
, , c > 0,
H(p1,p2,...,pn), , :
n
1
H ( p1 , p2 ,..., pn ) c pi ln
p
i 1
i
pi 0

c c = 1/ln k, :

H ( p1 , p2 ,..., pn )

p log

i 1
pi 0

n
1
pi log k pi
pi
i 1
pi 0

- k = 2, :
n

H ( p1 , p2 ,..., pn ) pi log 2 pi
i 1
pi 0

- , ,
. , [-1996], [Admek -1991] .
1: 0 ,
.
2: log2 n ( p1 = p2 = ... = pn = 1/n).

10 -

694


. - , - , H S. (
) S .
3: Sk , k-.
H(Sk ) = k.H(S).
4: S , ,
L(S) H(S).
. () H(S) Lmin(S) H(S) + 1.
, , ,
.
- .
#include <stdio.h>
#include <math.h>
#define log2(x) log(x)/log(2)
#define MAX 100
const double p[MAX] = {0.2, 0.2, 0.15, 0.15, 0.10, 0.10, 0.05, 0.05};
const unsigned n = 8; /* */
/* */
double calcEntropy(const double *p, const unsigned n)
{ unsigned i;
double sum;
for (sum = i = 0; i < n; i++)
sum -= p[i]*log2(p[i]);
return sum;
}
/* */
double calcValue(const double *p, const unsigned *l, const unsigned n)
{ unsigned i;
double sum;
for (sum = i = 0; i < n; i++)
sum += p[i]*l[i];
return sum;
}
/* */
void calcLengths(unsigned *l, const double *p, const unsigned n)
{ unsigned i;
for (i = 0; i < n; i++)
l[i] = (unsigned) ceil(log2(1.0 / p[i]));
}
int main(void) {
unsigned i;
double entr;
unsigned l[MAX];
printf("\n\n, : ");
for (i = 0; i < n; i++)

10 -

695

printf("%2.2lf ",p[i]);
entr = calcEntropy(p,n);
printf("\n : %8.5lf",entr);
printf("\n : %8.5lf",entr + 1);
calcLengths(l,p,n);
printf("\n : ");
for (i = 0; i < n; i++)
printf("%u ",l[i]);
printf("\n : %2.2lf",calcValue(p,l,n));
return 0;
}

entropy.c
:
, : 0.20 0.20 0.15 0.15 0.10 0.10 0.05 0.05
: 2.84644
: 3.84644
: 3 3 3 3 4 4 5 5
: 3.40

. , ,
L2 = 1,29 /. , S2. Lmin(S2) = 0,654 . , Lmin(S3) = 0,533.
? 3 4, ,
( ) - .
:
1. ? ?
2. - ?
3. 1 2, .

10.6.2.
1975 . , , -, 1977 . IEEE Transactions on
Information Theory, - . ,
.

. ,
, . ,
.
LZ77 ( ) 2 KB 16 KB
16 64 ( ASCII). , .
1978 . ,
, LZ78,
. ,

10 -

696

LZ78 LZ77.
, -, , -
. , LZ77, LZ78 .
,
, ,
, SQ
,
. 80-

,
. 1984 . IEEE Computer.
, Unisys,
LZ78, LZW --, -
.
,
.
-,
COMPRESS, VAX UNIX.
PC MS-DOS.
. 1985 . System Enhancement Associates
ARC, LZ78, .
PKARC PKWare, ,
- , LHarc , ARJ
PKZIP PKWare, ARC .
LZ78, - LZ77,
-, !
- LZW, , , .
CompuServe Information Service .
GIF LZW . TIFF ( ) PostScript ( )
LZW ().

10.6.3.

, . .
. ,
: ( . MOdulator DEModulator).
, . .
, .
CCITT V.42, IBM, British
Telecom, Bell Laboratories, Unisys .
512 KB 250 . , . .

.

10 -

697

, , . ,
LZ78 , LZW,
4558302 10.12.1985 ., Sperry Corp. (- Unisys Corp.). -
- V.42bis
Unisys Corp. LZW.

10.6.4.
, -
. , , . - ,
. " ?", .

, . ,
, .
,
, , -.
.
,
, , .
( )
.
, .
, , ( ).
. -
:
initTable();
while (!eof(input)) {
word = getWord(input);
if ((dictionaryIndex = findIndex(dictionary,word)) < 0) {
writeOut(output,word);
add2Dictionary(dictionary,word);
}
else
writeOut(output,dictionaryIndex);
}

- . ,
. , - ,
:
1. (), .
2. .
3. .
,
. . ,
,
. - , ,
, . ,

10 -

698


, .
:
, ?

10.6.5. LZ77.
-
LZ77. , , ,
.
, , .
,
. : -
. - ,
.
.
( ),
(p,l,c), :
1. p
2. l ()
3. c ,
l , - l
, l ,
. 10.6.5. 42- -
16- .

-,

10.6.5. LZ77: .
- " ", 21.
, : 21, 4, "". 4 . ..
? -
, : 0, 0, c, c ,
. ,
.
:
1. LZ77.
2. c, .. (p,l,c), (p,l)?
3. (0,0,c) ,
. - .

10.6.6. LZSS.
LZSS LZ77 : .
, ,
LZSS .

10 -

699

, ,
, - .
lw , ls . ,
- , log2 (lw.ls),
lw.ls, LZ77. - .
LZSS , . .
- , - .
, .

, .
.
,
( 2.4.). ,
. ,
,
. , :
, .
LZSS
, .
, , . - . ,
, a .
8, -
.
:
1. LZSS LZ77.
2. ?

10.6.7. FLZ. LZ77


LZ77, : ( 10.3.9.),
"" . . LZ77
, , ,
, , ,
. :
"backaconbacon"

"bacon" LZ77,
3, " bac" "on", 12-
50% . , FLZ, ,
.
"bacon", - , : " acon", 5 !
, ,
. ,
PKZIP 258 .
, FLZ,
. LZ77, , FLZ
. , .
. , .
. ,

10 -

700

: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx". FLZ.
.
,
. ,
.
:
1. FLZ LZ77.
2. -: ?
3. .

10.6.8. LZW.
, LZW, LZ77 LZ78.
LZW , - 4096 .
256 256- ASCII.
, - 1. 4096
, log2 4096 = 12 . 256
, 50% , 8- , , 12 .
(- ) -
. , , . . 16 ,
12 . 12 , 50-
, - , - .
:
1. , ?
2. ?
LZW, , (
!) . ,
. 256- ,
.
, . ,
, ,
. , .
, . ,
(, ),
. :
. , , , ,
, . :
initTable();
ch = getChar(input);
str = ch;
while(!eof(input)) {
ch = getChar(input);
if ((dictionaryIndex = findIndex(dictionary,str+ch)) < 0) {
writeOut(output,findIndex(str));
add2Dictionary(dictionary,str+ch);
str = ch;
}
else

10 -

701

str = str + ch;


}
writeOut(output,findIndex(dictionary,str));

initTable() 256- ,
str.
ch getChar().
findIndex(), str+ch 1,
. ,
(add2Dictionary()), . , str. , str+ch .. .
LZ77 LZW
. , -
. . ,
. - , , .
. .
. .
. ,
20 , : 12 8 .
256 , , . . 1.
(n) n ,
! 10.6.8. - ,
: abracadabragabramabracadabragabra.
: 0, 1, 6, 0, 2, 0, 3, 7, 9, 4, 14, 0, 5, 17, 11, 13, 8, 0, 16, 23.
? ,
ASCII , 33- 33.8 = 264 .
, 7 ,
33.3 = 99 . 20 .
(), 20.8 = 160 . , 16
, 4 , 4.20 = 80
. , .
, , ,
.
, . .
, . , ,
, ,
- . ,
, . ,
.. .
#

ch

str+ch

0
1
2
3
4
5
6

B
C
D
G
M
R

str

1
1
1
1
1
1
1

10 -
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

b
r
a
c
a
d
a
b
r
a
g
a
b
r
a
m
a
b
r
a
c
a
d
a
b
r
a
g
a
b
r
a

ab
br
ra
ac
ca
ad
da
ab
abr
ra
rag
ga
ab
abr
abra
am
ma
ab
abr
abra
abrac
ca
cad
da
dab
br
bra
ag
ga
gab
br
bra

b
r
a
c
a
d
a
b
r
a
g
a
b
r
a
m
a
b
r
a
c
a
d
a
b
r
a
g
a
b
r
a

702
0
1
6
0
2
0
3
0
7
6
9
4
0
7
14
0
5
0
7
14
17
2
11
3
13
1
8
0
4
16
1
8

7
8
9
10
11
12
13

14

15
16

17
18
19

20

21

22

23
24

25

B
R
A
C
A
D
A

G
A

A
M
A

A
G

0
1
6
0
2
0
3

9
4

14
0
5

17

11

13

8
0

16

0
1
6
0
2
0
3

9
4

14
0
5

17

11

13

8
0

16

23

7
14

7
14
17

11

13

16

8
23

b
r
a
c
a
d
a
ab
r
ra
g
a
ab
abr
a
m
a
ab
abr
abra
c
ca
d
da
b
br
a
g
ga
b

10.6.8. LZW: abracadabragabramabracadabragabra.


. ,
, .
cScScp, S e ( ), c p
. , cS , cSc .
cScScp.
, , c (?), , , ,
cS , , cSc . cS,
cSc . c,
. S, , cS .
c p. c cSc ,
p cScp .
cSc, - . ,
cSc. ? :
, . . , .
,
, .
-
, , .

10 -

703

, , :
, ,
, . ,
. :
initTable();
getCode(oldCode);
writeOut(output,getStr(dictionary,oldCode));
while(!eof(input)) {
getCode(input,code);
if (!inTable(code)) {
str = getStr(dictionary,oldCode);
str = str + str[0];
}
else
str = getStr(dictionary,code);
writeOut(output,str);
add2Dictionary(oldCode,str[0]); /* , . */
oldCode = code;
}

LZW :
#include
#include
#include
#include
#define
#define
#define
#define
#define
#define

<stdio.h>
<string.h>
<stdlib.h>
<process.h>

MAX_S 10
CHAR_CNT 256
DICT_SIZE 4096
ENCODED_SIZE 1000
MAX_MSG_LEN 1000
NOT_FOUND (unsigned)(-1)

const char *msg =


"abracadabragabramabracadabragabraLALALALALALALALALALALALALALALA";
char dictionary[DICT_SIZE][MAX_S];
unsigned dictIndex;
unsigned encoded[ENCODED_SIZE];
unsigned encIndex;

/*
/*
/*
/*

*/
*/
*/
*/

void initTable(void) /* */
{ unsigned i;
for (i = 0; i < CHAR_CNT; i++) {
dictionary[i][0] = i;
dictionary[i][1] = '\0';
}
dictIndex = CHAR_CNT;
}
unsigned findIndex(char *s) /* */
{ unsigned i;
for (i = 0; i < dictIndex; i++)
if (0 == strcmp(s,dictionary[i]))
return i;
return NOT_FOUND;
}

10 -

void add2Dictionary(char *s) /* */


{ strcpy(dictionary[dictIndex++],s); }
void LZWencode(const char *msg) /* LZW */
{ unsigned dictIndex, len;
char ch, str[MAX_S], strch[MAX_S];
initTable();
encIndex = 0;
*str = ch = *msg++; *(str+1) = '\0';
while ('\0' != *msg) {
ch = *msg++;
strcpy(strch,str);
strch[len = strlen(strch)] = ch; strch[len+1] = '\0';
dictIndex = findIndex(strch);
if (NOT_FOUND == dictIndex) {
encoded[encIndex++] = findIndex(str);
add2Dictionary(strch);
*str = ch; *(str+1) = '\0';
}
else {
str[len = strlen(str)] = ch; str[len+1] = '\0';
}
}
encoded[encIndex++] = findIndex(str);
}
void LZWdecode(char *decodedMsg) /* LZW */
{ unsigned code, oldCode, ind, len;
char str[MAX_S], str2[MAX_S];
initTable(); ind = 0;
oldCode = encoded[ind++];
strcpy(decodedMsg,dictionary[oldCode]);
while(ind < encIndex) {
code = encoded[ind++];
if (code >= dictIndex) {
strcpy(str,dictionary[oldCode]);
str[len = strlen(str)] = *str; str[len+1] = '\0';
}
else
strcpy(str,dictionary[code]);
strcat(decodedMsg,str);
strcpy(str2,dictionary[oldCode]);
str2[len = strlen(str2)] = *str; str2[len+1] = '\0';
add2Dictionary(str2);
oldCode = code;
}
}
void printEncodedMsg(const unsigned *encoded, const unsigned encIndex)
{ unsigned ind;
printf("\n\n :\n");
for (ind = 0; ind < encIndex; ind++)
printf("%u ", encoded[ind]);
printf("\n");

704

10 -

705

}
int main(void) {
char decodedMsg[MAX_MSG_LEN];
printf("\n\n :\n%s",msg);
LZWencode(msg);
printEncodedMsg(encoded, encIndex);
LZWdecode(decodedMsg);
printf("\n :\n%s", decodedMsg);
return 0;
}

lzw.c
:
:
abracadabragabramabracadabragabraLALALALALALALALALALALALALALALA
:
97 98 114 97 99 97 100 256 258 103 263 97 109 266 260 262 257 97 265 272
76 65 276 278 277 280 279 282 281 284
:
abracadabragabramabracadabragabraLALALALALALALALALALALALALALALA

, ,
. /
. , .
. - , LZW
, , - 4096 .

. . ,
, ,
. , 256
, .
,
.
LZW . ,
.
. - - ( 2.4.).
80%,
.
, . ch (
: __+ch).

, .
,
, , ,
. , , . , LZW , , . , - ZIP ARJ
LZ77. (, , .)

10 -

706

:
1. , ?
?
2. , ( )?
3. 10.6.8. ,
.
4. , - ,
, .
5. LZW? ?
6. LZW LZ77.
7. LZW.
8. LZW .

10.6.9. GIF. CompuServe


- LZW, CompuServe
: GIF. - GIF
. GIF, GIF87 GIF89. . , - , GIF89 , .
,
, . LZW
GIF, [Blackstock-1993]:
1. .
2. .
, ,
256 . , ASCII :
,
. .
,
.
n, 2n 0 2n1. 2n
. ,
<EOI> ( . End Of Information) <CC> ( . Clear Code),
2n 2n+1 .
n + 1 . GIF n + 1 .
- . <EOI>
: <EOI>.
. <CC> . 2n 2n + 1,
2n + 2.
<CC> , ,
. <CC> ,
. . 4095. (GIF 12 .)
<CC> , . , -, ,
.
GIF .
: 40 , - 6 ,
12. k = n + 1 .

10 -

707

2k 1, k = k + 1,
, 1 -. , -
, , , -
. .
k = n + 1, k .
, k 2k 1
, 2k , .
, .
:
1. ?
2. LZW.

10.6.10.
- ( 9.1.)
.
,
8 , 16 . ,
: "", "", "" "".
_, 10.6.10.

10.6.10. ( )
_ : "", "", "" "".
: 16 + 8 + 8 + 16 + 8 + 8 + 8 + 8 = 80 . , ( 10.6.10.) 48 (8 + 16 + 8 + 16 = 48),
. . 40%.

10.6.10. _
: "", "", "" "".

,
. ,
, , ,
.
:
1. FLZ ( 10.6.7.) ?.
2. ?
3. LZW "", "",
"" "". ?

10 -

708

10.6.11.

. , Stac Electronics
Stacker . -
Central Point Software PC Backup. Microsoft , Stacker DoubleSpace (- DriveSpace)
MS-DOS 5.0 , - Stac Electronics
Windows.
.
,
1,7:1 2,1:1 , . , . ,
- . , , 5-10%,
. , -
, . Stacker
DoubleSpace , .
. ,
, , . - . :
,
. ,
, . ,
, ,
, .
, ,
. , ,
.
, .
,
, .
,
. , , ,
, .
, - .
, /, -
/ ,
.
:
1.
?
2. ,
.

10 -

709

10.6.12. LZW
,
(LZW, 10.6.8.) 5 - ( 10.5.2.).
, -- , . , LZW . - -
.

AA
/
/ (A)
A
/
\ (B)
/ (A)
\
AB
\ (B)
\
B

10.6.12. : {A, B, AB, AA}.


- LZW
. , LZW ( ) . , (
), . - .
( ) , . , .
, , ,
, . , {A, B, AB, AA} 10.6.12. (, ,
).
, 1/4 (
10.6.12.).

AA 1/4
/
/ (A)
A 1/4
/
\ (B)
/ (A)
\
AB 1/4
\ (B)
\
B 1/4

10.6.12. : {A, B, AB, AA}, .


( 1/3,
A 1/3, 10.6.12.):
AA
/
/ (A) 1/3
A
3/4 /
\(B) 1/3
/ (A)
\

AB
\ (B)

10 -

710
1/4 \
B

10.6.12. : {A, B, AB, AA}, .


, LZW - , , ,
, .. LZW .
.
- X . X LZW X. - X, . ,
, . -
, .
, .
, . , ? .
,
( ) .
-
. ,
( ), LZW
0 1 . - .
LZW ,
, . . . .
, ,
.
LZW . LZW
. ,
. - , . ,
.
LZW ( [Williams-1991]).
:
1. - LZW .
2. LZW - .
3. LZW - LZ77?

10.7.
10.7.1.
-
/ , CS&Q ( . coarser sampling
and/or quantization). , ,
24-. "" 3 , -

10 -

711

. ,
1/8.
, , . ,
, .
. ,
,
. 12- . . . 24- . ,
, . - 4 .
8- ,
.
( ) /
, . .
JPEG. [Smith-1998]
:
-
.

10.7.2. JPEG
, , ,
,
100%. . , -
.
- .
X(t) F(f). ( ):

1
2

F( f )
X (t )

1
2

X (t )e

i 2ft

F ( f )e

i 2ft

dt

df

, , :

F( f )

1 N 1
X (t )e
N t 0
N 1

X ( f ) F (t )e

i 2ft
N

i 2ft
N

f 0

,
: - , . , 50% , 5% .
- JPEG,
. Joint Photographers Experts Group. JPEG DCT ( . Discrete Cosine Transform). ( -
-, , ,

10 -

712

, .) DCT
, , ,
. ? DCT,
- . ,
129 () 0 128. 256 , 1 127, : 0, 1, 2, 3, ,
127, 128, 127, , 3, 2, 1. , ,
, . 129
, .
JPEG 64 .
88 . 256 . 0 255
1 . 64 .
20 ( 2 ). 20 (2) , . JPEG
(x y 88, u v ):

(2 x 1)u (2 y 1)v
b( x, y) cos
cos

16
16

88 88, . . 64
64 ( ). , .
JPEG
. 88
DCT.
.
, 88.
, , . - . (
10.7.2.) , ( 10.7.2.)
.
1
1
1
1
1
2
2
4

1
1
1
1
1
2
2
4

1
1
1
1
2
2
2
4

1
1
1
1
2
2
4
4

1
1
2
2
2
2
4
8

2
2
2
2
2
4
8
8

2
2
2
4
4
8
8
16

4
4
4
8
8
8
16
16

10.7.2. , .
1
2
4
8
16
32

2
4
4
8
16
32

4
4
8
16
32
64

8
8
16
32
64
128

16
16
32
64
128
128

32
32
64
128
128
256

64
64
128
128
256
256

128
128
128
256
256
256

10 -
64
128

713
64
128

128
128

128
256

256
256

256
256

256
256

256
256

10.7.2. , .

- . ,
, 10.7.2. ( [Smith-1998]).
,
( 10.3.9.).
( 10.4.2.),
. 10.7.2. -
( 10.7.4.).

10.7.2a. .

10.7.2. JPEG: 1:1, 1:10 1:45.


:
1. GIF JPEG. ?
2. JPEG .

10.7.3. . MPEG
. , . , . . ,
, . ,
, - . .

10 -

714

- MPEG (
. Moving Pictures Experts Group). JPEG MPEG
, ( 10.3.7.), (
10.3.8.) . , JPEG MPEG.
, ,
.
MPEG : .
JPEG,
. I-picture ( . intra-coded
picture). MPEG P-picture ( . predictive-coded
picture) B-picture ( . bidirectional predictive-coded picture).
- ,
. ,
MPEG .
I-picture, MPEG , . .
P-picture. MPEG P-picture I-picture,
, : B-picture,
() , .
MPEG : . ,
. : B-picture
, . (. .
P-picture B-picture),
, B-picture, I-picture.
. MPEG
, ,
. , : IBBBPBBBP
MPEG IPBBBPBBB.
. ,
( 1024).
P-picture? - ,
. P-picture , . 64, 63, , 63.
, ,
.
,
. . P-picture
,
. ,
- ,
(
, 10.3.9.).
, - ( 10.7.2.).
MPEG 1616.
.
, , ,
. . P-picture .
6 88: 4 2 .
. . ,
.
( , 4 ).

10 -

715

, 88 .
,
.
MPEG . , , , "";
( );
, .
:
1. JPEG MPEG.
2. FLZ MPEG?

10.7.4.
42 (214
114 ). , , .
, 300:1 (
10.7.4.). , MPEG,
.
. - ,
. ,
, - . ,
.

10.7.4. : 1:1, 1:20 1:50.


-
. .
. V . Vi, Vi Vi+1
V V . Vi

. -
i, - . Wi
Vi V. Vi+1 Vi Wi.
Vi Wi .
- : ab(x) = (ax+b).
,
. ,
< ab(x), cd(x)> = ac db. xy = 1 , x = y. -
( 10.7.4. [1,1]).
a = 2j b = k.
, . ,
- , .

10 -

716

,
.

10.7.4. .
- ,
: , , , ,
, , .
, .
JPEG-2000 XXI
.
:
JPEG MPEG.

10.7.5.

.
, .
.
.
,
(, , , .),
. ,

.
20:1 50:1
. 50:1 90:1
. 100:1 ,
(. preview),
.
, ,
, . ,
, , JPEG MPEG
( 10.7.2. 10.7.3.). JPEG ,
, .
: -
,
. . ,
- ,
- JPEG. ,

10 -

717

JPEG,
, -.
, ,
24- ( ) .
, : .
- , .
, . , . :
.
:
1. .
2. - ?

10.8.
10.8.1.
10.1.
, ( 10.3.1.).
10.2.
escape ,
( 10.3.1.).
10.3.
SI SO (
10.3.1.).
10.4.
10.3.1. .
10.5.
10.3.2.
10.6.
( 10.3.2.)?
10.7.
(
0) ( 10.3.2.)? -
?
10.8.
(
10.3.2.), , , , ?
10.9.
( 10.3.2.)
( 10.3.1.). ? ?

10 -

718

10.10.
156 256-
( 10.3.3.).
10.11.
10.3.3. (
10.3.1.) ( 10.3.2.) .
10.12.
10.3.4.
10.13.
10.3.4.
10.14.
10.3.4. , 8 .
10.15.
-
10.3.5.
10.16.
-
( 10.3.5.):
;
;
, , , , Java.
10.17.
( 10.3.5.).
10.18.
( 10.3.5.)?
10.19.
, ( 10.3.5.).
10.20.
10.3.5.
10.21.
, 3 ( ) ( 10.3.5.)? ?
10.22.
- ( 10.3.6.). , .
10.23.
,
( 10.3.6.)?
10.24.
10.3.6. .

10 -

719

10.25.

( 10.3.7.):
) ;
) .
10.26.
( 10.3.7.).
10.27.
10.3.8.
, , . ?
10.28.
( 10.3.8.)
. -.
. ?
10.29.
10.3.8. 10.3.7.
10.30.
( 10.3.9.) Z
escape , ZZ? ZZZ? ZZZZ?
10.31.
( 10.3.9.)
: ZAZZZZZSDHDGSDGHGZGZGZHJGG, Z escape .
10.32.
, k ( 10.3.9.).
k?
10.33.
( 10.3.9.)
( 10.3.1.).
10.34.
, (
10.3.9.) ?
10.35.
PackBits ( 10.3.10.) ( 10.3.9.).
10.36.
PackBits ( 10.3.10.) 10.3.4.
10.37.
10.4.1.
10.38.
( 10.4.1.).

10 -

720

10.39.
- ( 10.4.1.)?
10.40.
- ( 10.4.1.),
? ?
10.41.
, , -, (
10.4.1.).
10.42.
- ( 10.4.1.) ?
10.43.
- ( 10.4.1.).
10.44.
- ,
( 10.4.1.)?
10.45.
( 10.4.2.) :
a
b
c
d
e
)
)
)
)

0,70
0,10
0,30
0,17

0,10
0,20
0,30
0,17

0,10
0,20
0,20
0,17

0,05
0,10
0,15
0,17

0,03
0,20
0,05
0,16

f
0,02
0,20
0,00
0,16

- ( 10.4.1.). ?
10.46.
( 10.4.2.)? ?
10.47.
, , ( 10.4.2.), .
10.48.
( 10.4.2.) - ( 10.4.1.).
10.49.
10.4.2. ,
.
10.50.
10.4.2. .
10.51.
10.4.2. .
10.52.
.
, ( 10.4.2.)?

10 -

721

10.53.
,
5 , ( 10.4.2.)?
10.54.
( 10.4.2.).
10.55.
, ( 10.4.3.)?
10.56.
( 10.4.3.)
?
10.57.
(
10.4.3.) ? ? ?
10.58.
( 10.4.4.)?
10.59.
( 10.4.4.).
10.60.
( 10.4.4.) ( 10.4.2.).
10.61.
( 10.4.5.) (
10.4.2.). - ? ?
10.62.
( 10.4.4.).
10.63.

( 10.5.).
10.64.
10.5.
10.65.
( 10.5.)
( 10.4.2.). ?
10.66.
( 10.5.) , ,
?
10.67.
10.5.1.
10.68.
10.5. , 10.5.1. -
?

10 -

722

10.69.
escape ( 10.5.1.).
10.70.
10.5.2.
10.71.
-
( 10.5.2.)?
10.72.

- ( ), 10.5.2.
10.73.
- ( 10.5.2.).
10.74.
MNP-5 ( 10.5.3.).
?
10.75.
10.5.3. ?
10.76.

( 10.6.).
10.77.

( ) ( 10.6.).
10.78.
( 10.6.)
( 10.4.2.) ( 10.4.5.)?
10.79.
( 10.6.1.)? ?
10.80.
- ( 10.6.1.)?
10.81.
1 2 10.6.1., .
10.82.
, ( 10.6.4.)?
10.83.
LZ77 ( 10.6.5.).
10.84.
LZ77 ( 10.6.5.) c, .. (p,l,c),
(p,l)?

10 -

723

10.85.
(0,0,c) LZ77 ( 10.6.5.)
, . -
.
10.86.
LZSS ( 10.6.6.) LZ77 ( 10.6.5.).
10.87.
LZSS ( 10.6.6.)?
10.88.
FLZ ( 10.6.7.) LZ77 ( 10.6.5.).
10.89.
FLZ ( 10.6.7.) -:
?
10.90.
FLZ ( 10.6.7.).
10.91.
, LZW ( 10.6.8.)
? ?
10.92.
, ( 10.6.8.)?
10.93.
10.6.8. ,
.
10.94.
, 10.6.8. ,
LZW , .
10.95.
LZW? 10.6.8. ?
10.96.
LZW ( 10.6.8.) LZ77 ( 10.6.5.).
10.97.
LZW ( 10.6.8.).
10.98.
LZW ( 10.6.8.) (
10.4.2.).
10.99.
GIF ( 10.6.9.)?
10.100.
GIF ( 10.6.9.) LZW ( 10.6.8.).
10.101.
FLZ ( 10.6.7.) 10.6.10. ?.

10 -

724

10.102.

( 10.6.10.)?
10.103.
LZW ( 10.6.8.) "",
"", "" "". ?
10.104.

( 10.6.11.)?
10.105.
,
( 10.6.11.).
10.106.
- LZW ( 10.6.12.).
10.107.
LZW - (
10.6.12.).
10.108.
LZW - LZ77 ( 10.6.12.)?
10.109.
( 10.7.1.) - .
10.110.
GIF ( 10.6.9.) JPEG ( 10.7.2.). ?
10.111.
JPEG ( 10.7.2.).
10.112.
JPEG ( 10.7.2.) MPEG ( 10.7.3.).
10.113.
FLZ ( 10.6.7.) ( 10.5.2.)
MPEG ( 10.7.3.)?
10.114.
( 10.7.4.) JPEG (
10.7.2.) MPEG ( 10.7.3.).
10.115.
( 10.7.4.) (
10.7.5.).
10.116.
- (
10.7.5.)?

10 -

725

10.8.2.
10.117.
(WinZip,
ARJ, AIN, RAR .)
.

10.118.
:
( 10.3.1.);
( 10.3.2.);
( 10.3.3.);
( 10.3.5.);
( 10.3.6.);
( 10.3.7.);
( 10.3.9.), escape
Z;

10.119.
, .
10.120. -
10.118. -
.
10.121.
, 10.3.4., 10.5.3., 10.7.2. 10.7.3.
10.122.
( 10.3.8.) (
10.4.) ( 10.5.) .
10.123.
A = {(51), (18), (53), (10), (55), (3), (50), (29), (20), (52), (54),
(500)}. .
) ;
) || *, [] ,
). B = { | *, || = max {|| | *, []P}}, P
,
60 ( [-1995]).
10.124.

:
;
:
, ;
, ;
.

10 -

726

10.125.
,
.
10.126.
?
10.127.
, , ,
, , ,
,
, . . ,
( 10.6.10.).

727

[-1992] ., , ,
, 1992.
[-1993] ., , . , 1/1993, , 1993.
[-1996] ., , .
PC&MAC World, 4/1996, , 1996.
[,-1980] ., . ,
, , , 1980.
[-1989] ., , , , 1989.
[-1984] ., , , , 1984.
[, -1973] , . , , I , ,
,1973.
[,-1990] ., . ,
, . , 4/1990, , 1990.
[-1979] ., . , , , , 1979.
[-1993] ., , . +, 1/1993,
, 1993.
[-1994] E., , . +,
3/1994, , 1994.
[-1998] ., , . Computer,
10/1998, , 1998.
[-5/1998] ., , 5/1998,
. Computer, 1998.
[-2000] ., , , , 2000.
[, -1977] ., . , , , , 1977.
[-1980] ., , , , 1980.
[-1989] . , 1, , , 1989.
[-1996] ., ,
, , 1996.
[-1998] ., , TopTeam Co, ,
1998.
[-1998a] ., , . Computer, 8/1998, ,
1998.
[-1998b] ., , .
Computer, 1/1998, , 1998.
[-1998c] ., , . PC Magazine/, 12/1998,
, 1998.
[-1998d] ., , . Computer,
10/1998, , 1998.
[-1998e] ., , . Computer, 8/1998, ,
1998.
[-1998f] ., .
, . Byte/, 7-8/1998, , 1998.
[-1998g] ., "
", - ComputerNews, 27/1998, , 1998.
[-1999a] ., , . PC Magazine/, 11/1999,
, 1999.

728

[-1999b] ., - , . PC Magazine/,
10/1999, , 1999.
[-1999c] ., , .
Byte/,
9-10/1999, , 1999.
[-1999d] ., , . Byte/, 9-10/1999,
, 1999.
[-1999f] ., k- , . PC
Magazine/, 3/1999, , 1999.
[-1999g] ., , PC Magazine/, 1/1999, , 1999.
[-1999h] ., , .
Computer 1/1999, , 1999.
[-1999i] ., , , .
Byte/, 1/1999, , 1999.
[-1999j] ., , . Computer,
1/1999, , 1999.
[-1999k] ., , . PC Magazine/, 1/1999, ,
1999.
[-1999l] ., k- , . PC
Magazine/, 3/1999, , 1999.
[-1999k] ., . , .
Byte/, 11/1999, , 1999.
[-2000a] ., - , . Byte/, 3/2000,
, 2000.
[-2000b] ., , . PC Magazine/, 2/2000, ,
2000.
[-2001a] ., , .
, , 2001.
[-2001b] ., , . Byte/,
, 2001.
[-2001c] ., . , .
Byte/, , 2001.
[-2001d] ., , . Byte/, ,
2001.
[-2001e] ., , . Computer, , 2001.
[-2001f] ., , . PC Magazine/, , 2001.
[-2001g] ., , . PC
Magazine/, , 2001.
[, -1989] ., . , , . ,
2/1989, , 1998.
[-1988] ., , . , 4/1988, , 1988.
[-1987] ., , , ,
, , 1987.
[ .-1989] . . ,
, , , 1989.
[,-1988] ., . , , .
, 4/1988, , 1988.
[, , -1995] ., . , . , ,
Asio, , 1995.
[, , -1980] ., . , . ,
. , , , 1980.
[-1995] ., . , , ,
, 1995.

729

[-II] http://www.b-info.com/places/Bulgaria/Royal
[-1996] ., Pascal. , ,
1996
[-1998] ., , - , ,
1998.
[-1993] ., ?, .
, 1/1993, , 1993.
[-1987] ., , . , 1/1987, , 1987.
[-1995] ., , , 1995.
[-1980] ., + = , , ,
1980.
[-1995] ., , . , , 1995.
[-1995] . , , , , 1995.
[Adams-1980] Adams D. Hitchhikers guide to the galaxy. Harmony books. 1980.
[Admek-1991] Admek J. Foundations of Coding. A Wiley-Interscience Publications. 1991.
[Aho, Hopcroft, Ullman-1974] Aho ., J. Hopcroft, J. Ullman. The Design and Analysis of
Computer Algorithms. Addison-Wesley Publishing Company. 1974.
[Aho,Hopcroft,Ullman1987] Aho A., J. Hopcoft, J. Ullman. Data Structures and Algorithms.
Addison-Wesley. 1987.
[ANSIC]
ISO/IEC
9899:1999
Programming
languages-C.
http://www.ansi.org;
http://www.iso.ch
[ANSIC-2] Rationale for ANSI Systems. http://www.lysator.liu.se/c/rat/title.html
[Ayres-1962] Ayres F. Theory and Problems of Matrices. Schaum. 1962.
[Bentley-1986] Bentley J. Pearls of Programming. Addison-Wesley. 1986. ( :
., , , , 1990)
[Bentley-1990] Bentley J. More Programming Pearls. Addison-Wesley Publishing Company.
1990.
[Blackstock-1993]
Blackstock
S.
LZW
and
GIF
explained.
http://www.lexitech.com/bobrich/steve.htm
[Bollobas-1979] Bollobas B. Graph Theory, an introduction course. Verlag. 1979.
[Bondy, Murty-1976] Bondy J., U. Murty. Graph Theory with Applications. Elsevier NorthHolland. 1976.
[Brassard,Bratley-1996] Brassard G., P. Bratley. Fundamentals of Algorithmics. Prentice-Hall.
1996.
[Brown-1972] R. J. Brown. Chromatic scheduling and the chromatic number problem.
Management Science, 19:451-463, 1972.
[Channon-1993] Channon C. Claude Elwood Channon Collected Papers. IEEE Press. 1993.
[Chiba,Nishizeki,Abe,Ozawa -1985] Chiba N., T. Nishizeki. A Linear Algorithm for Embedding
Planar Graphs Using PQ-Trees. J. of Comp. and Sys. Sci.. vol. 30. pp. 54-76. 1985.
[Christofides-1975] Christofides N. Graph Theory-an Algorithmic Approach. Academic Press.
1975. ( : H., - , ,
, 1978.)
[ComputerNews-19941] - ComputerNews, 5, , 1994.
[ComputerNews-19942] - ComputerNews, 6, , 1994.
[Cormen, Leiserson, Rivest-1997] Cormen T., C. Leiserson, R. Rivest. Introduction to
algorithms. MIT Press. 1997.
[Crochemore-1994] Crochemore M., R. Wojcieh. Text Algorithms. Oxford University Press.
Oxford. 1994.
[Culberson-1993] J. Culberson. Iterated Greedy Graph Coloring and the Difficulty Landscape.
Tech. Rep. TR 92-07, Dept. Comp. Sci., Univ. Alberta, Edmonton, Alberta T6G 2H1. Canada. 1992.
[Dor, Zwick-1996] Dorit D., U. Zwick. Median Selection Requires (2+epsilon)n Comparisons. In
Proc. IEEE Symposium on Foundations of Computer Science, pp. 125-134. 1996.

730

[Dunne-1987] Dunne P. A result of k-valent graphs and its application to a graph embedding
problem. Acta Informatica, 24, pp.447-459. 1987.
[Evans,Minieka-1998] Evans J., E. Minieka. Optimisation Algorithms for Networks and Graphs.
Marcel Dekker Inc. 1998.
[Fibonacci-1] http://www.ee.surrey.ac.uk/Personal/R.Knott/Fibonacci/fibFormula.html
[Flamig-1993] Flamig B. Practical Data Structures in C++. Azarona Software. 1993.
[France,Litman-1997] Frances M., A. Litman. On covering problems of codes. Theory of
Computing Systems, 30(2):pp.113-119, March/April. 1997.
[Fredman,Tarjan-1987] Fredman M., R. Tarjan. Fibonacci heaps and their uses in improved
network optimization algorithms. Journal of ACM 34, 3(July), pp. 596-615. 1987.
[Gabow, Galil, Spencer, Tarjan-1986] Gabow H., Z. Galil, T. Spencer, R. Tarjan. Efficient
algorithsms for finding minimum spanning trees in undirected and directed graphs. Combinatorica 6,
pp.109-122. 1986.
[Garey, Johnson-1979] Garey M., D. Johnson. Computers and Intractability: A Guide to the
Theory of NP-Completeness. Freeman. 1979.
[Garland-1998] Garland T. Fascinating Fibonaccis: Mystery and Magic in Numbers. Dale
Seymour Publications. 1998.
[Gibbons,Rytter-1987] Gibbons A., W. Rytter. Efficient parallel algorithms. Cambridge
University Press. 1987.
[Gregory, Rawlins - 1997] Gregory J., E. Rawlins. Compared to What? An Introdution to the
Analysis of Algorithms. Computer Science Press. 1997.
[Guinier-1991] Guinier D. The Multiplication of Very Large Integers Using the Discrete Fast
Fourier Transform. ACM-SIGSAC Review, Special Group on Security Audit and Control, vol. 9, no. 3,
pp. 26-36. 1991.
[Held-1991] Held G. Data Compression. John Wiley & Sons. 1991.
[HLJJTT-1996] Huss-Lederman S., E. Jacobson, J. Johnson, A. Tsao, T. Turnbull.
Implementation of Strassen's Algorithm for Matrix Multiplication, preprint. 1996.
[Hoffman-1997] Hoffman R. Data Compression in Digital Systems. Chapman&Hall. 1997.
[Hopcroft-Karp-1973] Hopcroft J., R. Karp. An algorithm for maximum matchings in bipartite
graphs. SIAM J. Computing, 2(4):pp.225-230. 1973.
[Horowitz-1977] Horowitz E., S. Sahni, Fundamentals of Data Structures. Pitman. 1977.
[Infoman] http://infoman.musala.com
[Jewell-1976] Jewell G. Text Compaction for Information Retrieval Systems. IEEE SMC
Newsletter, 5, No 1. 1976.
[Knuth-1/1968] Knuth D. The Art of Computer Programming. Volume I. Fundamental
Algorithms. MIT press. 1968. ( : . ,
1. , , , 1976.).
[Knuth-2/1968] Knuth D. The Art of Computer Programming. Volume II. Seminumerical
algorithms. MIT press. 1968. ( : ., , 2.
, , , 1978.).
[Knuth-3/1968] Knuth D. The Art of Computer Programming. Volume III. Sorting and
Searching. MIT press. 1968. ( : ., , 3.
, , , 1978.).
[Knott-1] http://www.mcs.surrey.ac.uk/Personal/R.Knott/Fractions/egyptian.html
[Korman-1979] Korman S. The graph-coloring problem. In: N. Christophides, P. Toth, and C.
Sandi, editors, Combinatorial Optimization, pp. 211-235. Wiley.1979.
[Kuera-1998] Kuera L., Combinatorial Algorithms. Adam Hilger. 1998.
[Loviglio-1997] Lociglio J., Deep Blue team awarded 100,000$ Fredkin price,
http://www.rci.rutgers.edu/~cfs/472_html/Intro/NYT_Intro/ChessMatch/DeepBlueTeamAwarded.html
[Magic-1] http://user.chollian.net/~brainstm/four.html
[Mathworld-a] http://www.math.utu.fi/research/automata/decidres.html

731

[Micali,Vazirani-1980] Micali S., V. Vazirani. An O(square root of V * E) Algorithm for Finding


Maximum Matching in General Graphs. Proc. 21st Annual Symposium on Foundation of Computer
Science, IEEE. 1980.
[MIT] Massachusetts Institute of Technology, http://www.mit.edu
[Motwani, Ragharan-1998] Motwani R., P. Ragharan. Randomized Algorithms. Cambridge
University Press. 1998.
[Nelson-1996] Nelson M., J.-L. Gailly. The Data Compression Book. M&T Books. 1996.
[Papernov, Stasevic-1965] Papernov A., G. Stasevic. A method of information sorting in
computer memories. Problems of Information Transmission 1, pp. 63-75. 1965.
[Parberry-1995] Parberry I. Problems on Algorithms. Prentice-Hall. 1995.
[Pratt-1979] Pratt V. Shellsort and Sorting Networks. Garland. 1979.
[Primes-1] Ribenboim P. Selling primes. Math. Mag. 68:pp.175-182. 1995.
[Primes-2] http://www.utm.edu/research/primes/notes/conjectures/
[Primes-3] http://www.utm.edu/research/primes/notes/6972593
[Prize-2000] Millenium Prize Problems http://www.claymath.org/prize_problems/index.htm
[Reinelt-1994] Reinelt G. The Traveling Salesman. Computational Solutions for TSP
Applications. Springer-Verlag. 1994.
[Riesel-1994] Riesel H. Prime Numbers and Computer Methods for Factorization. Progress in
Mathematics. vol. 57, 1985; and vol. 126, 1994.
[RSA-78] Rivest R., A. Shamir, L. Adleman. A method of obtaining digital signatures and public
key cryptosystems. Communications of the ACM, 21(2):120-126. 1978.
[Russell,Norvig-1995] Russell S., P. Norvig. Artificial Intelligence: a modern approach. Prentice
Hall. New Jersey. 1995.
[Sedgewick-1990] Sedgewick R. Algorithms in C. Addison-Wesley Publishing Company. 1990.
[Sedgewick1992] Sedgewick R. Algorithms in C++. Addison-Wesley Publishing Company.
1992.
[Sedgewick-1996] Sedgewick R. Analysis of Shellsort and Related Algorithms. In: Josep Daz,
Maria Serna (Eds.): Algorithms - ESA '96, Fourth Annual European Symposium, Barcelona, Lecture Notes
in Computer Science, Vol. 1136, Springer, 1-11. 1996.
[Shell-1959] Shell D. A high-speed sorting procedure. Communications of the ACM 2 (7), 30-32.
1959.
[Shioura, Tamura, Uno-1997] Shioura A., A. Tamura, T. Uno. An Optimal Algorithm for
Scanning All Spanning Trees of Undirected Graphs. SIAM Journal on Computing,Volume 26, Number
3, pp. 678-692. 1997.
[Skiena-1997] Skiena S. The Algorithm Design Manual. Springer-Telos. 1997.
[Smith-1998] Smith S. The Scientist and Engineer's Guide to Digital Signal Processing.
Addison-Wesley Publishing Company. 1997.
[Thulassiramann, Swamy-1998] Thulassiramann K., M. Swamy. Graphs: Theory and
Algorithms. A Wilew-Interscience Publication John Wiley & Sons Inc. 1998.
[Timus] Ural State University Problem Set Archive http://www.timus.ru
[TopTeam-1997] TopTeam Co., - BYTE, , 1997.
[Wai-2000]
Wai,
L.
Approximate
Graph
Colouring,
http://web.singnet.com.sg/~melvin/graph.html
[Wayner-1996] Wayner P. Disappearing Cryptography. AP Professional. Boston. 1996.
[Web-d]. . http://www.chronicle.com/free/99/09/99090901t.htm
[Williams-1991]
Williams
R.
LZRW4:
Ziv
and
Lempel
meet
Markov,
http://www.cs.pdx.edu/~idr/unbzip2.cgi?compression/lzrw4.html.bz2.

732

733


0
0-1 , 462, 577, 600

2
2-3-4 , 166

3
3-COL, 394
3- , 394

4
4- , 585

A
ASCII, 170, 172, 611, 624, 630, 637, 640, 653
AVL, 165

B
bidirectional predictive-coded picture, 680
bit mapping, 611
bitmap, 623
B-picture, 680, 681
B-, 166

C
coarser sampling, 677
comma code, 641

D
DCT, 678, 679
deadline, 29, 403, 580
Deep Blue, 353, 389
diatomic encoding, 616
Discrete Cosine Transform, 678
DivX, 607
DoubleSpace, 675

E
EBCDIC, 613
escape , 623
escape , 623, 653, 686
exp-space, 352

F
FLZ, 666, 674, 681, 689

G
GIF, 607, 663, 673, 680, 690, 695

H
halfbyte packing, 613

I
IEEE, 34, 506, 646, 663, 695
intra-coded picture, 680
I-picture, 680

J
Java, 23, 26, 617, 685
Javascript, 28
JPEG, 607, 678, 690

K
k- , 166
k-, 399
k-, 317, 344

L
LPC, 620, 621
LZ77, 609, 663
LZ78, 609, 663
LZSS, 666, 689
LZW, 609, 663, 695

M
memoization, 69, 79, 105, 461, 462, 477, 504,
510, 512, 517, 522, 528, 539, 571
MP3, 607
MPEG, 607, 680, 691

N
non-deterministic polynomial time, 351
NP-, 351, 352, 355
NP-complete, 355
NP- , 355
NP-, 356
null suppression, 609
n- , 584

P
Perl, 28
PHP, 28
PKZIP, 607
PostScript, 663


P-picture, 680, 681
predictive-coded picture, 680
P-space, 352
P-, 351
p-, 332
p-, 332, 345

Q
quantization, 677

R
run-length encoding, 622
r-, 337, 362

S
shift in, 610
shift out, 610
SI, 610, 623, 684
smart , 500, 558
SO, 610, 623, 684
Stacker, 607, 675

T
TIFF, 607, 663
t-, 254

U
Unicode, 637

, 137
, 520
, 522, 560
, 651, 665
, 654
, , 163
, 436, 454
, 172
, 395, 472, 557
, 519
, 591, 598
, 188, 276, 566
, 67, 127
, 318, 566
, , 299
, 322, 566
, 280, 303, 343, 566
, 272, 341, 566
-, 271, 566
, 456, 639
-, 456
, 438
- , 388

734
-

, 388
- , 386
- , 387
, 567
, 112
, 645, 676
, 94
, 100

, 329
, 347
, 164, 185, 247, 485, 666
, 683
, 520
, 460, 683
, 617, 685, 694
, 518
- , 518
, 90
, 272
, 244, 695
- , 387
, 228
, 223, 397, 401
, 52, 507
, 611, 615, 622, 684
, 227
, 412
, 518
, 56
, 239, 249
, 434
, 23, 204, 211, 219, 234, 455
, 441, 455
, 40, 436, 439,
454, 694

, 82
, 31
, 567, 593
, 381
, 438, 454
, 73
, 189
, 188
, 629
, 598

, 22, 593


, 57, 197
, 43, 116
, 598
, 251
, 582, 586, 602
, 450

, 585, 613, 625, 661


, 585
, 153, 178, 188
, 156, 160,
164, 189, 485, 486
, 427
, 24, 151, 195, 242, 255, 352,
427, 456, 496, 587
, 336, 399
, 234
, 176
, 691
, 336, 372, 399, 575, 601
, 403
, 145, 187
, 314
, 23, 271, 341, 347, 352
, 140, 145, 151, 183, 672, 691
, 32
, 254, 349
, 402
, 359, 399
, 148, 184
, 459
, 158
, 158
, 327
-, 552, 553, 563
, 226, 271, 576
, 309
, 177
, 414
, 310
, 577
, 17
, 439, 455, 507, 559
, 153, 278, 279, 349, 404
, 163, 247
, 379
, 404
, 208
, 162

, 25, 42, 67, 119

735
, 393, 436, 454, 605
, 568
, 613, 684
, 145, 151, 184
, 519, 560
, 351
, 270
, 101
, 234
, 658, 665, 689
, 25, 44, 116

, 579
, 369
, 460, 471, 577, 579
, 379, 394, 462, 694
, 286, 394
, 354
, 351
, 357, 390
, 235
, 691
, 605
, 175
, 551, 562
, 663, 675
, 68, 119, 170
, 175, 185

, 302, 343
, 382
, 166, 189, 208,
247, 485
, 175
, 156
, 148
, 348
, 378, 677
, 404
, 227
V' , 253
, 401
, 212, 222
, 456
, 661
, 683
, 13, 27, 63, 198, 219, 265, 319, 438,
443, 518

, 519

, 297
-, 170
, 22
, 480, 557, 694
, 176
, 242, 249
, 677
, 679
, 160
, 439
, 346
, 351
, 353
-, 170
, 351
, 160, 189
, 254, 324
, 402
, 170, 191, 197, 696
, 585
, 641, 687
, 611, 624,
666, 679, 686, 691
, 621
, 613
, 609
, 627, 640
, 174, 180
, 85
, 225
, 257, 311
, 312
, 607
, 684, 691
, 608, 677
, 522, 560
, 503, 518
, 522, 560
, 566
, 358
, 152, 255, 605
, 252
, 254
, 42, 625
, 318, 352, 576, 577, 601
, 395
, 398
, 355
, 502
, 339
, 449
, 289

736

, 570, 600
, 588, 605
, 132, 405
, 160, 189, 315
, 438
, 13, 22
, 50, 117
, 302, 343, 663
, 480, 532, 557
, 139, 145, 148, 151, 183, 187,
189, 425
, 19, 682
, 211, 225, 233, 417
, 175
, 152
, 358
, 160, 189
, 104
, 50, 117
, 438

, 131, 404
, 414, 453, 454
, 397
, 293, 296
, 399
, 270, 281
, 325, 345
, 336
, 570, 604
, 506
, 653
, 226
, 620
, 257, 280, 298, 302,
303, 343
, 257
, 256, 258, 265, 291
, 256, 258
, 39
, 204, 232, 413, 424, 453
, 413,453, 456
, 694
, 50
, 49, 117
, 519
, 220
, 349
, 199, 434, 454
, 194
, 378


, 199, 231
, 199, 231
k- , 401
k , 347
, 286, 342, 566
r-, 362
, 598
, 363, 573, 604
, 318, 403, 605
, 31
, 654, 677, 690
, 588, 604
, 608, 609
, 376, 377
, 318, 322, 324
, 253, 280, 310, 342
, 170

, 275
- , 70
- , 398
- , 489, 500, 558
- , 283, 355, 364, 391
- , 281, 341
- , 264, 340, 400
- , 264, 340
- , 396
- , 72
, 544
, 268, 340
, 276, 294, 336, 345
, 544
, 519
, 518
, 324
, 347, 493, 544
, 383
, 354
, 56
, 271
, 352
, 518
, 153
, 70, 119, 176
, 72, 119

, 32
, 275
, 603
, 272
CRC, 173

737
, 566
, 160, 184, 188, 693
, 604
, 351
, 262, 313
, 259, 261
, 388
--, 160
, 259, 262, 284, 290, 306,
311, 340, 352, 382
, 160, 587
, 146
, 489, 497, 694
, 194, 231, 237, 403, 425
, 51, 289, 291, 342, 693
, 290
, 289, 349
, 140
, 140, 537
, 43, 116
, 628, 686
, 460, 476, 487, 503,
530, 567
, 379
, 576
, 264
, 381
,
486, 557
, 398
, 403
, 251, 303
, 299
, 251, 300
, 605
, 47, 112
,
170
, 177
, 618, 680, 691
, 270, 340
, 45, 209
, 337, 362
, 575

, 395
, 399
, 224, 396
, 28, 91, 122, 191, 507, 511, 559, 617,
618, 685, 693
, 381
, 438


, 404
, 76, 81
, 230, 234
, 130, 188, 208, 209, 210, 233, 234,
279, 410, 456, 634, 637, 639, 687
, 188, 207, 210
/1, 618
, 338, 339, 348
, 449
, 302, 343
, 217, 220, 456
, 641, 649, 656
, 376
, 279, 341

, 279
, 171
, 519
, 152
, 395
, 603
, 352
, 270
, 613, 691
, 253, 330, 348, 403
, 290, 348, 403
, 238, 245, 249
,
238, 249
,
240, 249
, 310
, 293
, 292
, 264, 336
, 160
, 197, 412
, 611, 619, 622, 684, 691
, 50, 678
, 626
, 502
, 270
, 322, 344, 352, 576, 577, 601
, 386
, 140, 151, 188, 456, 634,
694
, 170
, 460, 477
, 267, 340
, 518
, 255
, 42, 127
, 44, 116

738
, 580
, 254
, 460
, 307
- , 276
- , 276

, 625, 630, 640, 656, 659


, 173, 248
, 332
, 397
, 515
, 87
, 626, 686
, 407
, 400
, 314
, 47
, 33, 114
, 372
, 548, 562
, 366
, 337
, 251
, 65
, 549
, 38
, 704
, 664, 692
, 44
, 412
, 61
, 154
, 164
, 172

, 320, 321
, 145, 148, 161, 177, 189, 195,
238, 428
, 171
, 33, 114
, 188
, 188, 519
, 519
, 427
, 228, 229
, 25, 93, 101, 123
, 351
, 352, 496


, 620
, 222
, 217, 410, 414, 453
, 114, 193, 204, 230,
454
, 199, 205, 231
, 212, 233
, 211, 416, 433, 454
, 191, 210, 234
, 212, 222
, 228
, 256
, 177
, 255
, 175, 183, 187
, 501, 558
, 410
, 620
, 151, 219, 257, 427
, 438
, 139
, 646, 655, 695
, 91, 122, 129, 211
-, 425
, 590
, 13, 27, 63, 137, 191
, 603
, 297
, 225
, 50
, 257
, 223

, 412, 424
, 339, 346
, 250
, 500
, 383
, 210, 233
, 639
, 298, 305
, 302
, 298
, 299
, 230
, 480, 489, 558
, 482, 489,
558
, 554
, 100, 225
, 52
, 639

739
, 605
, 530
, 156
, 351
, 587
, 240

, 294, 342
, 355
, 682
, 663, 675
, 43, 116
, 188, 207
, 28, 145, 160, 166, 188, 191, 195, 204,
239, 243, 433, 485, 519, 695
, 279, 436, 454, 460,
475, 557, 604, 694
, 293
, 198,
203, 229, 433
-, 174
, 174
, 280, 298, 303, 341
, 216, 233

, 38, 64
, 52
, 354, 589
, 65, 91, 105, 119, 128, 162, 185,
189, 246, 459, 504, 538, 559
, 245, 456
, 598, 606
, 271, 332, 341, 352, 412
-, 20
, 271, 279, 293, 297, 340
-, 271, 340
, 518
, 518
, 60
, 617, 685
, 279, 293, 298, 341
, 284
, 192, 212
, 678

, 682
, 367, 391, 394, 582
, 286, 342, 378, 390, 586,
593, 597, 603
, 107


, 522
, 168
, 173
, 173
-, 180
- , 171
- , 170
-, 168, 174, 180
- , 174
, 25
, 582, 585
, 584
, 42
, 499, 558
, 367, 582, 602
, 198, 204, 219, 231, 410, 456
, 439
, 60
, 337
, 438
, 609, 619, 629, 644, 649, 651, 663,
673, 686, 692

, 414
, 460
, 35
, 628, 661
, 332
, 264, 284, 357

740
, 187

() , 356
, 324
- , 164
- , 229
- , 229
, 33, 90, 105, 128, 480, 504, 516, 693
, 90
, 65
, 591
, 327
, 325
, 529
, 347
, 519, 523, 560

, 195, 205, 232


-, 609, 625, 639, 686
, 607, 625

, 40, 436, 475, 694

, 399

You might also like