You are on page 1of 21

TRNG I HC BCH KHOA H NI

VIN CNG NGH THNG TIN V TRUYN THNG


*

BI TP MN HC
K THUT LP TRNH

Nhm 40 :
Bch Vn Hi-CNTT1 20101464
Nguyn Duy Thnh-CNTT1 20102737
V Vn Hip-CNTT2 20101545
Gio vin

:
Lng Mnh B

H NI
Ngy 23 thng 3 nm 2012

Mc lc
1 Bi ton xp hu
1.1 Cch gii quy . . . . . .
1.1.1 Phn tch bi ton .
1.1.2 Thut ton . . . . .
1.1.3 Listing chng trnh
1.1.4 Kt qu . . . . . . .
1.2 Cch gii khng quy . . .
1.2.1 Phn tch . . . . . .
1.2.2 Listing chng trnh
1.2.3 Kt qu . . . . . . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

3
3
3
4
4
9
13
13
14
18

2 Bi ton thp H Ni
2.1 Cch gii quy . . . . . .
2.1.1 Phn tch . . . . . .
2.1.2 Thut ton . . . . .
2.1.3 Listing chng trnh
2.1.4 Kt qu . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

19
19
19
19
19
21

Hnh 1: Qun Hu (3,2) chim ct th 2, ng cho loi I th 5 v ng cho loi II


th 1

Bi ton xp hu

bi: Lit k tt c cc cch sp xp N qun hu trn bn c N x N sao cho chng


khng n c nhau.

1.1

Cch gii quy

1.1.1

Phn tch bi ton

nh s ct v s dng ca bn c t 0 n N 1. R rng N qun Hu c xp trn


N hng khc nhau. Do ta ch cn tm xem mi qun Hu c xp ct no. Gi colsi
l ch s ct ca qun Hu hng th i (i = 0 > N 1), colsi c th ly gi tr t 0 n
N 1. Ta s tm colsi cho i t 1 n N 1. Gi tr colsi = j c coi l tho mn khi c
(i, j) cha b qun Hu no trong s nhng qun Hu tm trc n. Mt qun Hu c
th n theo chiu ngang, dc v theo hai ng cho.
Mt qun Hu trc n (i, j) theo chiu ngang c ngha l qun Hu hng
i, iu ny l khng th xy ra do cch lm ca ta l mi hng ch xp ng mt qun
Hu. Qun Hu n theo chiu dc c ngha l qun Hu c ch s ct l j. i vi hai
ng cho, ta thy mt ng c i + j = const, (0 i + j 2N 2), ng kia c phng
trnh i j = const, (1 N i j N 1). Nh vy c tt c 2N 1 ng cho loi I
(i + j = const) v 2N 1 ng cho loi II (i j = const). Khi xp mt qun Hu vo
(i, j) th c ngha l ct j; ng cho loi I th (i + j) v ng cho loi II th (i j)
b chim, cc qun Hu sau ny khng c php t vo v tr c cng ct, ng cho vi
n.
biu din mt ct, ng cho b chim ta c th s dng 3 mng bool ai , bi , ci th
hin vic ct th i, ng cho loi I th i, ng cho loi II i b chim hay cha. Do
ngn ng C khng h tr mng c ch s m nn ta c th gn:
bool raw_c[2*N];
bool* c = raw_c + N;
3

Khi , c[i] == raw_c[i + N ] vi N i N 1.


1.1.2

Thut ton

Ta dng thut ton quy quay lui vi bi ton ny. C th gm cc bc nh sau:


1. Khi to a, b, c u bng true, c ngha l tt c cc ct vo ng cho lc u u
cha b chim. i = 0 l th t qun Hu ang xt, cng l ch s hng ca n.
2. Th cc gi tr j, 0 j N 1 l ch s ct ca qun Hu hin ti (hng i).
3. Nu (i, j) cha b chim, tc aj == bi+j == cij == true th chp nhn gi tr
j (gn colsi = j). nh du cc ct, ng cho tng ng vi (i, j) b chim
(aj = bi+j = cij = f alse). Nu i == N 1, tc l tm ra 1 kt qu th in n ra.
Cn li ta tm colsi+1 . Sau tr li (i, j) (tc l gn aj = bi+j = cij = true).
4. Nu (i, j) b chim th li tip tc th gi tr tip theo ca j.
5. Nu khng c kh nng no tho mn th quay li bc trc tm gi tr tip
theo ca colsi1 .
C th biu din bng m gi nh sau:
def find(i):
for j in range(0, N):
if a[j] and b[i+j] and c[i-j]:
cols[i] = j
a[j] = b[i+j] = c[i-j] = False
if i < N - 1:
find(i+1)
else:
PrintResult()
a[j] = b[i+j] = c[i-j] = True

1
2
3
4
5
6
7
8
9
10

1.1.3

Listing chng trnh

Listing chng trnh cha trong file queens_recursive.c, chng trnh c vit bng ngn
ng C theo chun C99 nn mt s trnh bin dch c c th khng bin dch c.

1
2
3
4
5
6
7
8
9
10
11

/*
* ==============================================================
*
*
Filename: queens_recursive.c
*
*
Description: Bi ton xp hu, cch gii quy
*
*
Version: 1.0
*
Created: 03/12/2012 07:12:42 PM
*
Revision: none
*
Compiler: gcc

12
13
14
15
16
17

*
*
Author: BOSS14420 (boss14420), boss14420@gmail.com
*
Company:
*
* ==============================================================
*/

18
19
20
21
22

#include
#include
#include
#include

<stdio.h>
<stdbool.h>
<string.h>
<stdlib.h>

23
24
25
26
27
28

int *cols;
bool *a,
*b,
*raw_c, *c;

// Ct th i
// ng cho I, i + j = const
// ng cho II, i - j = const

29
30
31

void init_state(int);
void free_state(int);

32
33

void find(int, int);

34
35
36
37

void print_result(int const*, int);


void print_result_board(int const*, int);
void (*print_func)(int const*, int) = print_result;

38
39
40

int main(int argc, char *argv[]) {


int n = 8;

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

// X l tham s dng lnh


if(argc >= 2) {
n = atoi(argv[1]);
if(n <= 0) {
fprintf(stderr, "Kch thc bn c khng hp l");
return EXIT_FAILURE;
}
}
if(argc == 3) {
if(!strcmp(argv[2], "-b") ||
!strcmp(argv[2], "--board"))
print_func = print_result_board;
else {
fprintf(stderr, "Usage: %s [NSIZE] [-b | --board]\n",
argv[0]);
return EXIT_FAILURE;
}
} else if(argc > 3) {

fprintf(stderr, "Usage: %s [NSIZE] [-b | --board]\n",


argv[0]);
return EXIT_FAILURE;

60
61
62

63
64

// Thc hin
init_state(n);
find(0, n);
free_state(n);

65
66
67
68
69

return EXIT_SUCCESS;

70
71

72
73
74
75
76
77
78
79
80
81
82
83
84

/*
* === FUNCTION ==============================================
*
Name: init_state
* Description: Khi to cc mng lu trng thi ca cc ct,
*
ng cho
* =============================================================
*/
void init_state(int n) {
a = (bool*) malloc(sizeof(bool)*n);
b = (bool*) malloc(sizeof(bool)*2*n);
raw_c = (bool*) malloc(sizeof(bool)*2*n), c = raw_c + n;

85
86

cols = (int*) malloc(sizeof(int)*n);

87
88
89
90
91
92
93
94
95

/* Ban u, tt c cc ct, ng cho u c gn


* l cha b chim */
for(int i = 0; i < n; ++i)
a[i] = b[i] = raw_c[i] = true;
for(int i = n; i < 2*n; ++i)
b[i] = raw_c[i] = true;
}
/* -----

end of function init_state

----- */

96
97
98
99
100
101
102
103
104
105
106
107

/*
* === FUNCTION ==============================================
*
Name: free_state
* Description: Gii phng b nh
* =============================================================
*/
void free_state(int n) {
free(a);
free(b);
free(raw_c);

108
109
110

free(cols);
}
/* -----

end of function free_state

----- */

111
112
113
114
115
116
117
118

/*
* === FUNCTION ==============================================
*
Name: print_result
* Description: In kt qu ra mn hnh
* =============================================================
*/

119
120
121

void print_result(int const* cols, int n) {


static int count = 0;

122
123

printf("Kt qu th %d:\n", ++count);

124
125
126

/* gi tr th i trong kt qu l ch s ct
* ca qun hu c ch s hng l i */

127
128
129
130
131
132
133

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


printf("%2d ", cols[i]);
}
printf("\n\n");
}
/* -----

end of function print_result ----- */

134
135
136
137
138
139
140
141
142
143
144

/*
* === FUNCTION ==============================================
*
Name: print_result_board
* Description: In ra bn c dng ASCII biu din kt qu thay
*
v in ch s v tr cc qun Hu
* =============================================================
*/
void print_result_board(int const* cols, int n) {
static int count = 0;

145
146

printf("Kt qu th %d:\n", ++count);

147
148
149
150

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


printf(" _");
putchar(\n);

151
152
153
154
155

for(int i = n-1; i >= 0; --i) {


for(int j = 0; j < cols[i]; ++j)
printf("|_");
printf("|*");

for(int j = cols[i]+1; j < n; ++j)


printf("|_");

156
157
158

printf("|\n");

159
160

161
162
163
164

printf("\n\n");
}
/* ----- end of function print_result_board

----- */

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

/*
* === FUNCTION ==============================================
*
Name: find
* Description: Tm v tr t qun hu ti hng th curr_row
*
tho mn yu cu
* =============================================================
*/
void find(int curr_row, int n) {
for(int curr_col = 0; curr_col < n; ++curr_col) {
if(a[curr_col] /* ct curr_col cha b chim */
/* ng cho loi I curr_row + curr_col cha b chim */
&& b[curr_row + curr_col]
/* ng cho loi II curr_row - curr_col cha b chim */
&& c[curr_row - curr_col])
{
cols[curr_row] = curr_col;

183

// Cp nht trng thi


a[curr_col] = b[curr_row + curr_col]
= c[curr_row - curr_col] = false;

184
185
186
187

if(curr_row < n - 1) {
// Tm cch xp hu hng tip theo
find(curr_row + 1, n);
} else {
print_func(cols, n);
}

188
189
190
191
192
193
194

// tr li trng thi c
a[curr_col] = b[curr_row + curr_col]
= c[curr_row - curr_col] = true;

195
196
197

198
199
200
201

}
}
/* -----

end of function find ----- */

1.1.4

Kt qu

Vi N = 8, c tt c 92 kt qu khc nhau (46 nu tnh 2 kt qu i xng nhau l 1)

10

11

C th in kt qu dng bn c trc quan hn, thay v cc con s ch v tr:


./queen_recursive 5 --board

Nu kt qu qu di, c th lu vo file. V d: vi N = 12 (c 14200 kt qu)


./queen_recursive 12 --board > qr12.txt

12

1.2
1.2.1

Cch gii khng quy


Phn tch

Theo thut ton quy:


1
2
3
4
5
6
7
8
9
10

def find(i):
for j in range(0, N):
if a[j] and b[i+j] and c[i-j]:
cols[i] = j
a[j] = b[i+j] = c[i-j] = False
if i < N - 1:
find(i+1)
else:
PrintResult()
a[j] = b[i+j] = c[i-j] = True
Gi s cu hnh hin ti ang l cols = (j0 , j1 , . . . , ji1 ) Ta thy:
Vic la chn gi tr ji trong khong t 0 n N-1 dng (2) c bt u ngay sau
khi tm c ji1 trc . V tip tc sau khi kt thc vic tm kt qu ng vi
cu hnh cols = (j0 , j1 , . . . , ji1 , ji 1),
Dng (5) c thc hin ngay sau khi chp nhn mt ji ,
Dng (10) c thc hin khi hoc l in ra mt kt qu, hoc l vic chp nhn j
dng (4) khng dn ra c mt kt qu ng.
Do ta c th kh quy bng php lp, dng mt bin i lu gi tr ca hng hin
ti. Cho ji th ln lt cc gi tr t 0 n N-1, nu tho mn th cp nht trng thi, tng
i ln 1 v tip tc vi i + 1. Cho n khi i == N 1 th in kt qu v tr li trng thi.
Nu khng cn ji no tho mn th gim i i 1 v tr li trng thi c. Qu trnh kt thc
khi i == 0 v khng cn gi tr j0 no tho mn na ( ht cu hnh th). Ta c m gi
nh sau:

1
2
3
4
5
6
7
8
9
10

def solve():
i = 0
cols[i] = -1
while True:
# Thu gia tri tiep theo
j = ++cols[i]
if j < N:
# Neu o (i, j) chua bi chiem
if a[j] && b[i+j] && c[i-j]:
a[j] = b[i+j] = c[i-j] = False

11
12
13
14
15
16

if i < N-1:
# Bat dau tim cols[i+1]
cols[++i] = -1
else:
PrintResult()

17

13

# Tra lai trang thai cu


a[j] = b[i+j] = c[i-j] = True

18
19

elif i > 0:
# Tro lai thu gia tri tiep theo cua cols[i-1]
j = cols[--i]

20
21
22
23

# Tra lai trang thai cu


a[j] = b[i+j] = c[i-j] = True
else:
break

24
25
26
27

1.2.2

Listing chng trnh

Listing chng trnh cha trong file queens_nonrecursive.c, chng trnh c vit bng
ngn ng C theo chun C99 nn mt s trnh bin dch c c th khng bin dch c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

/*
* ==============================================================
*
*
Filename: queens_nonrecursive.c
*
*
Description: Bi ton xp hu, cch gii khng quy
*
*
Version: 1.0
*
Created: 03/12/2012 07:12:42 PM
*
Revision: none
*
Compiler: gcc
*
*
Author: BOSS14420 (boss14420), boss14420@gmail.com
*
Company:
*
* ==============================================================
*/

18
19
20
21
22

#include
#include
#include
#include

<stdio.h>
<stdbool.h>
<string.h>
<stdlib.h>

23
24

void solve(int);

25
26
27
28

void print_result(int const*, int);


void print_result_board(int const*, int);
void (*print_func)(int const*, int) = print_result;

29
30
31

int main(int argc, char *argv[]) {


int n = 8;

14

32

// X l tham s dng lnh


if(argc >= 2) {
n = atoi(argv[1]);
if(n <= 0) {
fprintf(stderr, "Kch thc bn c khng hp l");
return EXIT_FAILURE;
}
}
if(argc == 3) {
if(!strcmp(argv[2], "-b") ||
!strcmp(argv[2], "--board"))
print_func = print_result_board;
else {
fprintf(stderr, "Usage: %s [NSIZE] [-b | --board]\n",
argv[0]);
return EXIT_FAILURE;
}
} else if(argc > 3) {
fprintf(stderr, "Usage: %s [NSIZE] [-b | --board]\n",
argv[0]);
return EXIT_FAILURE;
}

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

// Thc hin
solve(n);

56
57
58

return EXIT_SUCCESS;

59
60

61
62
63
64
65
66
67
68

/*
* === FUNCTION ==============================================
*
Name: print_result
* Description: In kt qu ra mn hnh
* =============================================================
*/

69
70
71

void print_result(int const *cols, int n) {


static int count = 0;

72
73

printf("Kt qu th %d:\n", ++count);

74
75
76

/* gi tr th i trong kt qu l ch s ct
* ca qun hu c ch s hng l i */

77
78
79

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


printf("%2d ", cols[i]);

15

80
81
82
83

}
printf("\n\n");
}
/* -----

end of function print_result ----- */

84
85
86
87
88
89
90
91
92
93
94

/*
* === FUNCTION ==============================================
*
Name: print_result_board
* Description: In ra bn c dng ASCII biu din kt qu thay
*
v in ch s v tr cc qun Hu
* =============================================================
*/
void print_result_board(int const *cols, int n) {
static int count = 0;

95
96

printf("Kt qu th %d:\n", ++count);

97
98
99
100

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


printf(" _");
putchar(\n);

101
102
103
104
105
106
107

for(int i = n-1; i >= 0; --i) {


for(int j = 0; j < cols[i]; ++j)
printf("|_");
printf("|*");
for(int j = cols[i]+1; j < n; ++j)
printf("|_");

108

printf("|\n");

109
110

111
112
113
114

printf("\n\n");
}
/* ----- end of function print_result_board

----- */

115
116
117
118
119
120
121
122
123
124
125
126
127

/*
* === FUNCTION ==============================================
*
Name: solve
* Description: Tm tt c cc cch sp xp qun hu tho mn
*
yu cu
* =============================================================
*/
void solve(int n) {
bool a[n];
// Ct th i
bool b[2*n];
// ng cho 1, i + j = const
bool raw_c[2*n], *c= raw_c + n; // ng cho 2, i - j = const
int cols[n];

16

128

// Init
for(int i = 0; i < n; ++i)
a[i] = b[i] = raw_c[i] = true;
for(int i = n; i < 2*n; ++i)
b[i] = raw_c[i] = true;

129
130
131
132
133
134

cols[0] = -1;
int curr_row = 0, curr_col = 0;

135
136
137

while(true) {
if((curr_col = ++cols[curr_row]) < n) {
if(a[curr_col] /* ct curr_col cha b chim */
/* ng cho loi I curr_row + curr_col cha b chim */
&& b[curr_row + curr_col]
/* ng cho loi II curr_row - curr_col cha b chim */
&& c[curr_row - curr_col])
{
// Cp nht trng thi
a[curr_col] = b[curr_row + curr_col]
= c[curr_row - curr_col] = false;

138
139
140
141
142
143
144
145
146
147
148
149

if(curr_row < n - 1) {
cols[++curr_row] = -1;
} else {
print_func(cols, n);

150
151
152
153
154

// tr li trng thi c
a[curr_col] = b[curr_row + curr_col]
= c[curr_row - curr_col] = true;

155
156
157

158

}
} else if(curr_row > 0) {
curr_col = cols[--curr_row];

159
160
161
162

// tr li trng thi c
a[curr_col] = b[curr_row + curr_col]
= c[curr_row - curr_col] = true;
} else
break;

163
164
165
166
167

168
169
170

}
/* -----

1.2.3

end of function solve ----- */

Kt qu

Kt qu ging vi kt qu ca cch gii khng quy. V d, vi N = 4:

17

18

Bi ton thp H Ni

bi: C 3 cc a, b, c. Trn cc a c mt chng gm n ci a ng knh gim dn t


di ln trn. Cn phi chuyn chng a t cc a dang cc c tun th qui tc: mi ln ch
chuyn mt a v ch c xp a c ng knh nh hn ln a c ng knh ln hn.
Trong qu trnh chuyn c php dng cc b lm cc trung gian.

2.1
2.1.1

Cch gii quy


Phn tch

Vi n = 1, ta ch vic chuyn a t cc a sang cc c.


Vi n = 2, ta c th di chuyn 1 a (ci nh hn) t cc a sang cc b, chuyn a cn li
cc a sang cc c v cui cng chuyn a cc b sang cc c. C ba bc di chuyn ny
hp l.
Lp lun tng t nh trn, ta c th di chuyn n a bt k (n > 1) nh sau:
1. Chuyn n 1 a t cc a sang cc trung gian b,
2. Chuyn a ln nht t cc a sang cc ch c,
3. Chuyn n 1 a t cc b sang cc c.
C th chng minh c vic di chuyn nh trn mt 2n 1 bc.
2.1.2

Thut ton

Cch lm nh trn a bi ton di chuyn n a v bi ton di chuyn n 1 a, ri n 2


a, . . . . Rt thch hp cho mt thut ton quy:
# Ham thuc hien viec di chuyen
def move(n, source, dest, mid):
if n > 1:
move(n-1, source, mid, dest)
move( 1, source, dest, mid)
move(n-1, mid, dest, source)
else:
print "Move 1 disk from " + source + " to " + dest

1
2
3
4
5
6
7
8
9

move(n, a, c, b)

10

2.1.3

1
2
3
4
5
6

Listing chng trnh

/*
* =============================================================
*
*
Filename: towerofhanoi.c
*
*
Description:

19

7
8
9
10
11
12
13
14
15
16
17

*
*
Version: 1.0
*
Created: 03/17/2012 02:24:36 PM
*
Revision: none
*
Compiler: gcc
*
*
Author: BOSS14420 (boss14420), boss14420@gmail.com
*
Company:
*
* =============================================================
*/

18
19
20
21

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

22
23

#define MAX_DISK 12

24
25

void move(size_t, char, char, char);

26
27
28
29
30
31
32
33

int main(int argc, char *argv[]) {


/* X l tham s dng lnh */
size_t ndisk;
if(argc != 2) {
fprintf(stderr, "Usage: %s NDISKS\n", argv[0]);
return EXIT_FAILURE;
}

34

ndisk = atoi(argv[1]);

35
36

if(ndisk > MAX_DISK || ndisk == 0) {


fprintf(stderr, "S a khng hp l\n");
return EXIT_FAILURE;
}

37
38
39
40
41

/* Thc hin vic di chuyn */


move(ndisk, a, c, b);

42
43
44

return EXIT_SUCCESS;

45
46

47
48
49
50
51
52
53
54

/*
* === FUNCTION ==============================================
*
Name: move
* Description: Di chuyn ndisk a t ct src n ct dst,
*
c th s dng ct trung gian mid
* =============================================================

20

55
56
57

*/
void move (size_t ndisk, char src, char dst, char mid) {
static size_t count = 0;

58

if(ndisk) {
move(ndisk - 1, src, mid, dst);
printf("Bc %2u: chuyn a t ct %c -> %c\n",
++count, src, dst);
move(ndisk - 1, mid, dst, src);
}

59
60
61
62
63
64
65
66

}
/* -----

2.1.4

end of function move

----- */

Kt qu

Vi n = 3, cn tt c 7 bc di chuyn; n = 4, cn 15 bc:

21

You might also like