Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 56

Trương Hoàng Phú - 20215628

Bài thực hành số 3 – Tuần 12


Contents
Bài 3.1. Dãy Lucas được định nghĩa bởi Ln = Ln-1 + Ln-2 với L0 = 2, L1 = 1. Hãy viết hàm tính số Lucas
thứ n..................................................................................................................................................2
Bài 3.2. Trên bàn cờ vua kích thước n*n có một quân mã đang ở ô (1, 1). Hãy đưa ra một dãy các
di chuyển của mã sao cho mỗi ô trên bàn cờ đều được đi qua đúng 1 lần (ô (1, 1) được xem là đã
đi qua)...............................................................................................................................................3
Bài 3.3. Một người xuất phát tại thành phố 1, muốn đi thăm tất cả các thành phố khác, mỗi thành
phố đúng 1 lần và quay về 1. Chi phí để đi từ thành phố i sang thành phố j là cij. Hãy tìm tổng chi
phí nhỏ nhất có thể...........................................................................................................................7
Bài 3.4. Cho dãy a có n phần tử. Một dãy con của a là dãy thu được bằng cách xóa đi một số phần
tử của a và giữ nguyên thứ tự các phần tử còn lại (có thể không xóa phần tử nào). Hãy tìm dãy
con tăng dài nhất của a...................................................................................................................11
Bài 3.5. Tính hệ số tổ hợp C(n, k)....................................................................................................15
Bài 3.6. Tìm ước chung lớn nhất của hai số nguyên a, b cho trước.................................................19
Bài 3.7. Sử dụng phương pháp khử đệ quy bằng stack, hãy liệt kê các xâu nhị phân độ dài n không
có k bit 1 nào liên tiếp.....................................................................................................................22
Bài tập 8: Cân đĩa............................................................................................................................28
Bài tập 9: Lập lịch cho y tá...............................................................................................................31
Bài tập 10: Khoảng cách Hamming..................................................................................................36
Bài tập 11: Lịch trình chụp ảnh.......................................................................................................40
Bài tập 12: Đếm đường đi...............................................................................................................47

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Tables of Figures
Hình 1 Đề bài bài 3.1.........................................................................................................................3
Hình 2 Code bài 3.1...........................................................................................................................3
Hình 3 Kết quả bài 3.1.......................................................................................................................3
Hình 4 Đề bài bài 3.2.........................................................................................................................4
Hình 5 Code bài 3.2 (1)......................................................................................................................5
Hình 6 Code bài 3.2 (2).....................................................................................................................5
Hình 7 Code bài 3.2 (3).....................................................................................................................5
Hình 8 Kết quả bài 3.2.......................................................................................................................6
Hình 9 Đề bài bài 3.3.........................................................................................................................8
Hình 10 Code bài 3.3 (1)...................................................................................................................9
Hình 11 Code bài 3.3 (2)...................................................................................................................9
Hình 12 Code bài 3.3 (3)...................................................................................................................9
Hình 13 Code bài 3.3 (4).................................................................................................................10
Hình 14 Kết quả bài 3.3...................................................................................................................10
Hình 15 Đề bài bài 3.4.....................................................................................................................13
Hình 16 Code bài 3.4 (1).................................................................................................................13
Hình 17 Code bài 3.4 (2).................................................................................................................13
Hình 18 Code bài 3.4 (3).................................................................................................................14
Hình 19 Code bài 3.4 (4)..................................................................................................................14
Hình 20 Kết quả bài 3.4...................................................................................................................14
Hình 21 Đề bài bài 3.5.....................................................................................................................17
Hình 22 Code bài 3.5 (1)..................................................................................................................17
Hình 23 Code bài 3.5 (2)..................................................................................................................17
Hình 24 Code bài 3.5 (3)..................................................................................................................18
Hình 25 Kết quả bài 3.5...................................................................................................................19
Hình 26 Đề bài bài 3.6.....................................................................................................................21
Hình 27 Code bài 3.6 (1)..................................................................................................................21
Hình 28 Code bài 3.6 (2)..................................................................................................................22
Hình 29 Kết quả bài 3.6..................................................................................................................22
Hình 30 Đề bài bài 3.7.....................................................................................................................24
Hình 31 Code bài 3.7 (1)..................................................................................................................24
Hình 32 Code bài 3.7 (2)..................................................................................................................24
Hình 33 Code bài 3.7 (3)..................................................................................................................25
Hình 34 Kết quả bài 3.7..................................................................................................................28
Hình 35 Đề bài bài 8........................................................................................................................30
Hình 36 Code bài 8 (1).....................................................................................................................31
Hình 37 Code bài 8 (2).....................................................................................................................31
Hình 38 Code bài 8 (3).....................................................................................................................31
Hình 39 Kết quả bài 8.....................................................................................................................32
Hình 40 Đề bài bài 9........................................................................................................................34
Hình 41 Code bài 9 (1).....................................................................................................................34
Hình 42 Code bài 9 (2).....................................................................................................................34
Hình 43 Code bài 9 (3).....................................................................................................................35
Hình 44 Code bài 9 (4).....................................................................................................................35
Hình 45 Kết quả bài 9.....................................................................................................................36
Hình 46 Đề bài bài 10......................................................................................................................38
Hình 47 Code bài 10 (1)...................................................................................................................39
Hình 48 Code bài 10 (2)...................................................................................................................39
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

Hình 49 Code bài 10 (3)...................................................................................................................39


Hình 50 Kết quả bài 10...................................................................................................................40
Hình 51 Đề bài bài 11......................................................................................................................43
Hình 52 Code bài 11 (1)...................................................................................................................43
Hình 53 Code bài 11 (2)...................................................................................................................43
Hình 54 Code bài 11 (3)...................................................................................................................44
Hình 55 Code bài 11 (4)...................................................................................................................44
Hình 56 Code bài 11 (5)...................................................................................................................44
Hình 57 Kết quả bài 11...................................................................................................................46
Hình 58 Đề bài bài 12......................................................................................................................50
Hình 59 Code bài 12 (1)...................................................................................................................50
Hình 60 Code bài 12 (2)...................................................................................................................51
Hình 61 Code bài 12 (3)...................................................................................................................51
Hình 62 Kết quả bài 12...................................................................................................................53

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Bài 3.1. Dãy Lucas được định nghĩa bởi Ln = Ln-1 + Ln-2 với L0 = 2,
L1 = 1. Hãy viết hàm tính số Lucas thứ n.

Hình 1 Đề bài bài 3.1

Hình 2 Code bài 3.1

Hình 3 Kết quả bài 3.1

//Truong Hoang Phu 20215628


IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

/*

Bài 3.1. Dãy Lucas được định nghĩa bởi Ln = Ln-1 + Ln-2 với L0 = 2, L1 = 1. Hãy viết hàm tính số
Lucas thứ n.

*/

int lucas(int n) {

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if(n<=1) return 2-n; //Trả về 2-n nếu n nhỏ hơn hoặc bằng 1

return lucas(n-1) + lucas(n-2); //Trả về hàm

/*****************/

//Truong Hoang Phu 20215628

Bài 3.2. Trên bàn cờ vua kích thước n*n có một quân mã đang ở ô
(1, 1). Hãy đưa ra một dãy các di chuyển của mã sao cho mỗi ô trên
bàn cờ đều được đi qua đúng 1 lần (ô (1, 1) được xem là đã đi qua).

Hình 4 Đề bài bài 3.2

Hình 5 Code bài 3.2 (1)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 6 Code bài 3.2 (2)

Hình 7 Code bài 3.2 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 8 Kết quả bài 3.2

//Truong Hoang Phu 20215628

/*

Bài 3.2. Trên bàn cờ vua kích thước n*n có một quân mã đang ở ô (1, 1).

Hãy đưa ra một dãy các di chuyển của mã sao cho mỗi ô trên bàn cờ đều được đi qua đúng 1 lần
(ô (1, 1) được xem là đã đi qua).

*/

#include <iostream>

using namespace std;

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

int n;

int X[100], Y[100]; //# Lưu tọa độ các bước di chuyển của quân mã

int mark[100][100]; //# Đánh dấu vị trí các ô mà quân mã đã di chuyển qua

//# Mảng hx, hy mô tả 8 vị trí quân mã có thể di chuyển kể từ vị trí hiện tại

const int hx[] = {1, 1, 2, 2, -1, -1, -2, -2};

const int hy[] = {2, -2, 1, -1, 2, -2, 1, -1};

//# In ra dãy các di chuyển tìm được

void print_sol(){

for (int j = 1; j <= n * n; ++j)

printf("(%d %d)\n", X[j], Y[j]);

exit(0);

//# Thuật toán quay lui

void TRY(int k){

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

int xx = X[k-1] + hx[i]; //Biến xx là toạ độ x có thể có của quân mã trong bước đi tiếp theo

int yy = Y[k-1] + hy[i]; //Biến yy là toạ độ y có thể có của quân mã trong bước đi tiếp theo

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if((xx>0 && xx<=n) && (yy>0 && yy<=n) && mark[xx][yy]==0){ //Nếu xx và yy hợp lệ và ô xx-
yy chưa được đánh dấu thì

mark[xx][yy] = 1; //Đánh dấu ô xx-yy

X[k] = xx; //Lưu toạ độ bước đi xx

Y[k] = yy; //Lưu toạ độ bước đi yy

if(k == n*n) print_sol(); //Nếu đã đi hết bàn cờ thì in kết quả

else{ //Nếu không thì

TRY(k+1); //Gọi hàm quay lui tìm tiếp bước đi khác

mark[xx][yy]=0; //Bỏ đánh dấu bước đi vừa rồi

}
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

/*****************/

int main(){

cin >> n; //Nhập kích thước bàn cờ

mark[1][1] = 1; //Đánh dấu ô 1-1 là đã đi

X[1] = Y[1] = 1; //Lưu lại tạo độ 1-1

TRY(2); //Gọi thuật toán quay lui

return 0;

//Truong Hoang Phu 20215628

Bài 3.3. Một người xuất phát tại thành phố 1, muốn đi thăm tất cả
các thành phố khác, mỗi thành phố đúng 1 lần và quay về 1. Chi phí
để đi từ thành phố i sang thành phố j là cij. Hãy tìm tổng chi phí nhỏ
nhất có thể

Hình 9 Đề bài bài 3.3

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 10 Code bài 3.3 (1)

Hình 11 Code bài 3.3 (2)

Hình 12 Code bài 3.3 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 13 Code bài 3.3 (4)

Hình 14 Kết quả bài 3.3

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

//Truong Hoang Phu 20215628

/*

Bài 3.3.

Một người xuất phát tại thành phố 1, muốn đi thăm tất cả các thành phố khác, mỗi thành phố
đúng 1 lần và quay về 1.

Chi phí để đi từ thành phố i sang thành phố j là cij. Hãy tìm tổng chi phí nhỏ nhất có thể

*/

#include <bits/stdc++.h>

using namespace std;

#define MAX 100

int n, c[MAX][MAX]; //# số thành phố và ma trận chi phí

int cmin = INT_MAX; //# chi phí đi lại nhỏ nhất giữa hai thành phố khác nhau

int best = INT_MAX; //# tổng chi phí nhỏ nhất cần tìm, ban đầu đặt bằng giá trị vô cùng lớn
INT_MAX = 2^31-1

int curr; //# tổng chi phí tới thời điểm hiện tại

int mark[MAX]; //# đánh dấu những thành phố đã đi

int x[MAX]; //# lưu giữ các thành phố đã đi

//# Đọc dữ liệu vào

void input(){

cin >> n;

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

for (int j = 1; j <= n; ++j){

cin >> c[i][j];

if (c[i][j] > 0) cmin = min(cmin, c[i][j]);

//# Thuật toán quay lui

void TRY(int k){

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

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if(mark[i]==0){ //Nếu thành phố chưa được đánh dấu

mark[i] = 1; //Đánh dấu thành phố

curr += c[x[k-1]][i]; //Tăng chi phí di chuyển

x[k] = i; //Lưu thành phố

if(k == n) { //Nếu đã đi hết tất cả các thành phố

curr += c[x[n]][1]; //Trở về thành phố 1

best = min(best,curr); //Ghi lại chi phí nhỏ nhất

curr -= c[x[n]][1]; //Trả lại chi phí trước đó

else TRY(k+1); //Thử cách đi khác

mark[i] = 0; //Bỏ đánh dấu hành phố

curr -= c[x[k-1]][i]; //Trả lại chi phí trước đó

/*****************/

int main() {

input(); //Nhập dữ liệu đầu vào

x[1] = 1; //Lưu thành phố 1

TRY(2); //Gọi hàm quay lui

cout << best; //In ra giá trị nhỏ nhất

return 0;

//Truong Hoang Phu 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Bài 3.4. Cho dãy a có n phần tử. Một dãy con của a là dãy thu
được bằng cách xóa đi một số phần tử của a và giữ nguyên thứ tự
các phần tử còn lại (có thể không xóa phần tử nào). Hãy tìm dãy con
tăng dài nhất của a.

Hình 15 Đề bài bài 3.4

Hình 16 Code bài 3.4 (1)

Hình 17 Code bài 3.4 (2)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 18 Code bài 3.4 (3)

Hình 19 Code bài 3.4 (4)

Hình 20 Kết quả bài 3.4

//Truong Hoang Phu 20215628

/*

Bài 3.4. Cho dãy a có n phần tử. Một dãy con của a là dãy thu được bằng cách xóa đi một số phần
tử của a và giữ nguyên thứ tự các phần tử còn lại

(có thể không xóa phần tử nào). Hãy tìm dãy con tăng dài nhất của a.

*/

#include <bits/stdc++.h>

using namespace std;

int a[1000], n;

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

int mem[1000]; //# mảng ghi nhớ lời giải các bài toán con đã được giải

//Đặt giá trị của cả mảng mem là -1

void init(){

memset(mem, -1, sizeof(mem));

//# Quy hoạch động,

//# Hàm lis(i) trả về độ dài dãy con tăng dài nhất kết thúc bởi a[i]

int lis(int i) {

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if (mem[i] != -1) { //Nếu mem[i] khác -1

return mem[i]; //Trả về mem[i]

int res = 1; //Khai báo biến res

for (int j=0; j<i; j++) { //Duyệt từng phần tử của mảng a

if (a[j] < a[i]) { //Nếu a[j] < a[i]

res = max(res, 1 + lis(j)); //gán res bằng max(res, 1 + lis(j))

mem[i] = res; //Gán mem[i] = res

return res; //Trả về res

/*****************/

//# Truy vét lời giải

void trace(int i){

for(int j = 0; j < i; j++){ //Duyệt theo i

if (a[j] < a[i] && mem[i] == 1 + mem[j]){ //Nếu dãy đang tăng và i, j được đánh dấu là thuộc
dãy con
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

trace(j); //Đệ quy tìm phần tử trước j

break;

cout << a[i] << " "; //In ra số thuộc dãy con

int main(){

init();

cin >> n; //Nhập n

for(int i = 0; i < n; i++) cin >> a[i]; //Nhập mảng

int res = 1, pos = 0; //Biến res tìm độ dài dãy con và biến pos lưu phần tử cuối cùng của dãy con
tăng dài nhất

for(int i = 1; i < n; i++){ //Duyệt cả mảng

//Tìm độ dài dãy con tăng dài nhất

if (res < lis(i)){

res = lis(i);

pos = i; //Lưu lại vị trí kết thúc

cout << res << endl; //In ra chiều dài dãy con

trace(pos); //Gọi ra dãy con

return 0;

//Truong Hoang Phu 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Bài 3.5. Tính hệ số tổ hợp C(n, k)

Hình 21 Đề bài bài 3.5

Hình 22 Code bài 3.5 (1)

Hình 23 Code bài 3.5 (2)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 24 Code bài 3.5 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 25 Kết quả bài 3.5

//Truong Hoang Phu 20215628

/*

Bài 3.5. Tính hệ số tổ hợp C(n, k)

*/

#include <iostream>

using namespace std;

int binom(int n, int k) { //Khai báo hàm bimon

if (k > n) return 0; //Nếu k>n trả về 0

if (k == 0) return 1; //Nếu k=0 trả về 1

return binom(n-1, k) + binom(n-1, k-1); //Trả về binom(n-1, k) + binom(n-1, k-1)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

int c[1000][1000]; //Khai báo mảng c lưu giá trị C n k

int binom2(int n, int k){ //Khai báo hàm bimon2

//# Khử đệ quy

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

for(int i=0; i<=n; i++){ //Duyệt theo n

c[i][0] = 1; //Gán C n 0 bằng 1

for(int j=1; j<=i ;j++){ //Duyệt theo k

c[i][j] = c[i-1][j] + c[i-1][j-1]; //Gán C i j = C i-1 j + C i-1 j-1

return c[n][k];//Trả về C n k

/*****************/

int main() {

int m; //Khai báo m

cin >> m; //Nhập giá trị của m

for (int n = 1; n <= m; ++n){ //Duyệt theo n

for (int k = 0; k <= n; ++k) //Duyệt theo k

printf("%d ", binom(n, k)); //In ra giá trị của C n k

printf("\n");

for (int n = 1; n <= m; ++n){ //Duyệt theo n

for (int k = 0; k <= n; ++k) //Duyệt theo k

printf("%d ", binom2(n, k)); //In ra giá trị của C n k

printf("\n");

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

return 0;

//Truong Hoang Phu 20215628

Bài 3.6. Tìm ước chung lớn nhất của hai số nguyên a, b cho trước.

Hình 26 Đề bài bài 3.6

Hình 27 Code bài 3.6 (1)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 28 Code bài 3.6 (2)

Hình 29 Kết quả bài 3.6

//Truong Hoang Phu 20215628

/*

Bài 3.6. Tìm ước chung lớn nhất của hai số nguyên a, b cho trước.

*/

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

#include <iostream>

using namespace std;

int gcd(int a, int b){ //Khai báo hàm gcd

if (b == 0) return a; //Nếu b=0 trả về a

return gcd(b, a % b); // Trả về gcd(b, a % b)

int gcd2(int a, int b){ //Khai báo hàm gcd2

//# Khử đệ quy

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if(b==0) return a; //Nếu b=0 trả về a

while(b!=0){ //Khi b khác 0

int tmp = b%a; //Khai báo biến tmp bằng b%a

a = b; //Gán a = b

b = tmp; //Gán b = tmp

return a; //Trả về a

/*****************/

int main() {

int a, b; //Khai báo a,b

cin >> a >> b; //Nhập giá trị a,b

cout << gcd(a, b) << endl << gcd2(a, b); //In ra giá trị

return 0;

//Truong Hoang Phu 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Bài 3.7. Sử dụng phương pháp khử đệ quy bằng stack, hãy liệt kê
các xâu nhị phân độ dài n không có k bit 1 nào liên tiếp

Hình 30 Đề bài bài 3.7

Hình 31 Code bài 3.7 (1)

Hình 32 Code bài 3.7 (2)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 33 Code bài 3.7 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 34 Kết quả bài 3.7

//Truong Hoang Phu 20215628

/*

Bài tập 7: Liệt kê xâu nhị phân

Sử dụng phương pháp khử đệ quy bằng stack, hãy liệt kê các xâu nhị phân độ dài n không có k bit
1 nào liên tiếp

*/

#include <bits/stdc++.h>

using namespace std;

struct state{
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

int i, j, old_L; //Vị trí trong xâu i, giá trị bit j, số bit 1 liên tiếp trước đó old_L

//# constructor

state(int _i = 0, int _j = 0, int _L = 0): //Giá trị mặc định

i(_i), j(_j), old_L(_L){}

};

int main() {

int n, k; //Độ dài xâu n và số bit liên tiếp k

cin >> n >> k; //Nhập giá trị của n, k

int x[n+1]; //Mảng lưu trữ xâu nhị phân

stack<state> s; //Vector lưu trạng thái xâu

//# number of consecutive suffix 1

int L = 0; //Số bit 1 liên tiếp

s.push(state(1, 0)); //Lưu trạng thái ban đầu của xâu

while (!s.empty()){ //

state &top = s.top();

//# if a new binary sequence is found

if (top.i > n){ //Nếu đã đi hết n bit

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

cout << x[i] << " \n"[i == n]; //In ra xâu

s.pop(); //Loại bỏ trạng thái

continue; //Tiếp tục vòng lặp tìm xâu

//# Khử đệ quy

/*****************

# YOUR CODE HERE # Truong Hoang Phu 20215628 */

if(top.j>0) L = top.old_L; //Nếu bit > 0 thì lưu lại L

if(top.j>1){ //Nếu bit > 1

s.pop(); //Loại trạng thái khỏi vector

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

continue; //Tiếp tục tìm xâu

if(L+1<k || top.j==0){ //Nếu chưa quá k bit 1 liên tiếp hoặc bit bằng 0 thì

x[top.i] = top.j; //Lưu lại giá trị bit j

top.old_L = L; //Lưu lại số lượng bit 1 liên tiếp

if(top.j) L = L + 1; //Nếu j là bit 1 thì tăng số bit 1 liên tiếp thêm 1

else L = 0; //Nếu là bit 0 thì đặt L về 0

s.push(state(top.i+1,0)); //Đẩy trạng thái vào vector

top.j++; //Tăng giá trị của bit j

/*****************/

return 0;

//Truong Hoang Phu 20215628

Bài tập 8: Cân đĩa


Bạn đang muốn kiểm tra xem một vật cho trước có đúng nặng M như người
ta nói hay không. Có một cân thăng bằng và n quả cân. Quả thứ i nặng mi.
Hãy chỉ ra một cách cân thỏa mãn.

Hình 35 Đề bài bài 8

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 36 Code bài 8 (1)

Hình 37 Code bài 8 (2)

Hình 38 Code bài 8 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 39 Kết quả bài 8

//Truong Hoang Phu 20215628

/*

Bài tập 8: Cân đĩa

Bạn đang muốn kiểm tra xem một vật cho trước có đúng nặng M như người ta nói hay không.

Có một cân thăng bằng và n quả cân. Quả thứ i nặng mi. Hãy chỉ ra một cách cân thỏa mãn.

*/

#include <bits/stdc++.h>

using namespace std;

//Struct lưu trạng thái của quá trình tìm kiếm

struct state{

int i, j, s; //Vị trí trong mảng i, giá trị j là -1,0,1 , tổng s

state(int _i = 0, int _j = 0, int _s=0): i(_i), j(_j), s(_s){} //Giá trị mặc định

};

int main() {

int n, M; //Số quả cân n và cân nặng M

cin >> n >> M; //Nhập gí trị cho n, M

int m[n+1]; //Mảng lưu cân nặng của các quả cân

for (int i = 1; i <= n; ++i) cin >> m[i]; //Nhập cân nặng cho từng quả

int x[n+1]; //Mảng x lưu quyết định chọn -1,0,1

stack<state> s; //Stack s lưu trữ trạng thái tìm kiếm s

//# sum of selected weights

int sum = 0;

//Đẩy 3 trạng thái ban đầu vào stack

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

s.push(state(1, -1, -m[1]));

s.push(state(1, 0, 0));

s.push(state(1, 1, m[1]));

while (!s.empty()){ //Nếu stack chưa rỗng

state top = s.top(); //Lấy phần tử đầu của stack ra để xét

if (top.i >= n){ //Nếu đã duyệt hết tất cả các quả cân

if (top.s == M){ //Nếu tổng các phần tử đã chọn bằng M

for (int i = 1; i <= n; ++i){ //Duyệt từng phần tử của mảng x

if (x[i] == -1) cout << '-' << m[i]; //Nếu giá trị là -1 thì in ra - m[i]

if (x[i] == 1) cout << '+' << m[i]; //Nếu giá trị là 1 thì in ra + m[i]

cout << "=" << M;

exit(0); //Dừng chương trình

s.pop(); //Xoá phần tử đầu của stack

continue; //Tiếp tục tìm

//# Khử đệ quy Truong Hoang Phu 20215628

s.pop(); //Xoá phần tử đầu của stack

x[top.i]=top.j; //Đặt x[i] là bit j

//Đẩy các trạng thái mới vào stack

s.push(state(top.i+1, -1, top.s-m[top.i+1]));

s.push(state(top.i+1, 0,top.s));

s.push(state(top.i+1, 1,top.s+m[top.i+1]));

cout << -1; //Nếu không có cách thì in ra -1

return 0;

//Truong Hoang Phu 20215628

Bài tập 9: Lập lịch cho y tá


Một y tá cần lập lịch làm việc trong N ngày, mỗi ngày chỉ có thể là làm việc
hay nghỉ ngơi. Một lịch làm việc là tốt nếu không có hai ngày nghỉ nào liên
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

tiếp và mọi chuỗi ngày tối đại làm việc liên tiếp đều có số ngày thuộc
đoạn [K1,K2] Hãy liệt kê tất cả các cách lập lịch tốt, với mỗi lịch in ra trên
một dòng một xâu nhị phân độ dài n với bit 0/1 tương ứng là nghỉ/làm việc.
Các xâu phải được in ra theo thứ tự từ điển.

Hình 40 Đề bài bài 9

Hình 41 Code bài 9 (1)

Hình 42 Code bài 9 (2)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 43 Code bài 9 (3)

Hình 44 Code bài 9 (4)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 45 Kết quả bài 9

//Truong Hoang Phu 20215628

/*

Bài tập 9: Lập lịch cho y tá

Một y tá cần lập lịch làm việc trong N ngày, mỗi ngày chỉ có thể là làm việc hay nghỉ ngơi.

Một lịch làm việc là tốt nếu không có hai ngày nghỉ nào liên tiếp và mọi chuỗi ngày tối đại làm việc
liên tiếp đều có số ngày thuộc đoạn [K1,K2].

Hãy liệt kê tất cả các cách lập lịch tốt, với mỗi lịch in ra trên một dòng một xâu nhị phân độ dài n
với bit 0/1 tương ứng là nghỉ/làm việc.

Các xâu phải được in ra theo thứ tự từ điển

*/

#include<bits/stdc++.h>

using namespace std;

const int MAX = 1000;

int n, k1, k2; //Số ngày làm việc và đoạn k1, k2

int x[MAX]; //Xâu nhị phân lưu ngày làm/nghỉ

int so1 = 0; //Lưu số ngày làm việc liên tiếp

//Hàm kiểm tra ngày hợp lệ không

bool check(int a, int i){

if(a==1) return true; //Nếu a=1 trả về true


IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

else{ //Nếu không thì

// neu ngay nay nghi -> kiem tra ngay truoc do, neu da nghi thi khong duoc nghi nua

if(i==0){ //Nếu ngày i nghỉ

if(x[a-1] == 0) return false; //Nếu mà ngày a-1 cũng nghỉ thì trả về false

else { //Nếu ngày a-1 làm

if(so1<k1) return false;

} else { //Nếu ngày i làm

if(x[a-1] == 0){ //Nếu mà ngày a-1 nghỉ

if(n-a+1 < k1) return false; //Nếu số ngày còn lại không thuộc đoạn [k1,k2] thì trả về false

} else { //Còn nếu mà ngày a-1 làm

if(so1>=k2) return false; //Nếu số ngày còn lại không thuộc đoạn [k1,k2] thì trả về false

return true; //Trả về true

//Hàm in ra kết quả

void solution(){

for(int i=1; i<=n; i++) cout<<x[i]; //Duyệt từng ngày và in ra

cout << endl;

//Hàm quay lui tìm chuỗi hợp lệ

void TRY(int a){

for(int i=0; i<=1; i++){ //Thử với ngày i làm việc hoặc không

if(check(a,i)){ //Kiểm tra hợp lệ

x[a] = i; //Lưu lại kết quả thử

int pre = so1; //Lưu lại số ngày làm việc liên tiếp (lvlt) trước đó

if(i == 1){ //Nếu ngày i làm

if(x[a-1] == 1) so1++; //Nếu ngày a-1 cũng làm thì tăng số ngày lvlt lên

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

else so1 = 1; //Không thì đặt là 1

} else { //Nếu ngày i không làm

so1 = 0; //Đặt số ngày lvlt là 0

if(a==n) solution(); //Nếu đã đủ ngày thì in ra kết quả

else TRY(a+1); //Nếu không thì tìm chuỗi khác

so1 = pre; //Đặt lại là số ngày lvlt trước đó

int main(){

cin >> n >> k1 >> k2; //Nhập dữ liệu

TRY(1); //Gọi hàm tìm chuỗi phù hợp

return 0;

//Truong Hoang Phu 20215628

Bài tập 10: Khoảng cách Hamming


Khoảng cách Hamming giữa hai xâu cùng độ dài là số vị trí mà ký tự tại vị trí
đó là khác nhau trên hai xâu. Cho S là xâu gồm n ký tự 0. Hãy liệt kê tất cả
các xâu nhị phân độ dài n, có khoảng cách Hamming với S bằng H. Các
xâu phải được liệt kê theo thứ tự từ điển.

Hình 46 Đề bài bài 10

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 47 Code bài 10 (1)

Hình 48 Code bài 10 (2)

Hình 49 Code bài 10 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 50 Kết quả bài 10

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

//Truong Hoang Phu 20215628

/*

Bài tập 10: Khoảng cách Hamming

Khoảng cách Hamming giữa hai xâu cùng độ dài là số vị trí mà ký tự tại vị trí đó là khác nhau trên
hai xâu.

Cho S là xâu gồm n ký tự 0. Hãy liệt kê tất cả các xâu nhị phân độ dài n, có khoảng cách Hamming
với S bằng H.

Các xâu phải được liệt kê theo thứ tự từ điển.

*/

#include<bits/stdc++.h>

using namespace std;

const int MAX = 20;

int N, H; //Độ dài xâu nhị phân N và kc Hamming H

int x[MAX]; //Xâu kết quả

int S[MAX]; //Xâu mặc định để so sánh

//Hàm nhập giá trị đầu vào //Truong Hoang Phu 20215628

void input(){

cin>>N>>H; //Nhập giá trị của N, H

for(int i=0; i<N; i++) S[i] = 0;

for(int i=0; i<N; i++) x[i] = 0;

//Hàm kiểm tra khoảng cách Hamming //Truong Hoang Phu 20215628

int checkHamming(int str1[], int str2[]){

int cnt = 0; //Biến tính khoảng cách Hamming

for(int i=0; i<N; i++){ //Duyệt từng kí tự trong xâu

if(str1[i] != str2[i]) cnt++; //Nếu khác thì tăng giá trị

return cnt; //Trả về biến cnt

//Hàm in ra kết quả nếu hợp lệ //Truong Hoang Phu 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

void solution(){

if(checkHamming(x,S) == H){ //Nếu khoảng cách Hamming bằng H

for(int i=0; i<N; i++) cout<<x[i]; //In ra xâu nhị phân

cout<<endl;

//Hàm quay lui sinh xâu hợp lệ //Truong Hoang Phu 20215628

void TRY(int a){

for(int i=0; i<=1; i++){ //Thử các giá trị 0 và 1

x[a] = i; //Thay x[a] bằng i

if(a == N-1) solution(); //Nếu đã đủ độ dài xâu thì in ra kết quả

else TRY(a+1); //Nếu không tìm xâu khác

int main(){

int T; //Số test case

cin >> T; //Nhập số test

while(T > 0){ //Khi chưa hết số test

input(); //Nhập giá trị đầu vào

TRY(0); //Gọi hàm tìm xâu hợp lệ

T--; //Giảm số test case còn lại

//Truong Hoang Phu 20215628

Bài tập 11: Lịch trình chụp ảnh


Superior là một hòn đảo tuyệt đẹp với n địa điểm chụp ảnh và các đường
một chiều nối các điểm chụp ảnh với nhau. Đoàn khách tham quan
có r người với sở thích chụp ảnh khác nhau. Theo đó, mỗi người sẽ đưa
ra danh sách các địa điểm mà họ muốn chụp. Bạn cần giúp mỗi người
trong đoàn lập lịch di chuyển sao cho đi qua các điểm họ yêu cầu đúng
một lần, không đi qua điểm nào khác, bắt đầu tại điểm đầu tiên và kết

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

thúc tại điểm cuối cùng trong danh sách mà họ đưa ra, và có tổng khoảng
cách đi lại là nhỏ nhất.

Hình 51 Đề bài bài 11

Hình 52 Code bài 11 (1)

Hình 53 Code bài 11 (2)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 54 Code bài 11 (3)

Hình 55 Code bài 11 (4)

Hình 56 Code bài 11 (5)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 57 Kết quả bài 11

//Truong Hoang Phu 20215628

/*

Bài tập 11: Lịch trình chụp ảnh

Superior là một hòn đảo tuyệt đẹp với n địa điểm chụp ảnh và các đường một chiều nối các điểm
chụp ảnh với nhau.

Đoàn khách tham quan có r người với sở thích chụp ảnh khác nhau. Theo đó, mỗi người sẽ đưa ra
danh sách các địa điểm mà họ muốn chụp.
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

Bạn cần giúp mỗi người trong đoàn lập lịch di chuyển sao cho đi qua các điểm họ yêu cầu đúng
một lần, không đi qua điểm nào khác,

bắt đầu tại điểm đầu tiên và kết thúc tại điểm cuối cùng trong danh sách mà họ đưa ra, và có tổng
khoảng cách đi lại là nhỏ nhất.

*/

#include <bits/stdc++.h>

using namespace std;

const int N = 1001;

int c[N][N]; //Ma trận chi phí di chuyển c

int place[N]; //Những địa điểm muốn đi

int leng; //Số địa điểm muốn đi

int x[N]; //Lưu lại các thành phố đã đi

int curr;

int best;

int cmin = INT_MAX; //Chi phí đi lại nhỏ nhất giữ hai thành phố khác nhau

//Đặt dữ liệu ban đầu

void init(){

x[0] = place[0]; //Lưu lại thành phố đầu tiên

x[leng] = place[leng]; //Lưu lại thành phố cuối cùng

curr = 0;

best = INT_MAX;

//Kiểm tra thành phố i đã đi qua hay chưa

int visit( int place, int k ){

for ( int i = 1; i <= k; i++) //Duyệt từng phần tử của x[i]

if (place == x[i]) return 0; //Nếu đã đi qua thì trả về 0

return 1; //Trả về 1

//Quay lui tìm chi phí nhỏ nhất

void process(int k){

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

for(int y = 1; y < leng ; y++){ //Duyệt theo từng địa điểm muốn đi

if ( !c[x[k-1]][place[y]]) continue; //Nếu có đường đi giữa 2 điểm thì tiếp tục

if ( !visit(place[y], k) ) continue; //Nếu chưa đi qua điểm y thì tiếp tục

if ((k + 1 == leng)) { //Nếu đã đi hết tất cả số điểm mong muốn

if(!c[place[y]][place[leng]]) continue; //Nếu có đường đi giữa 2 điểm thì tiếp tục

x[k] = place[y]; //Lưu lại địa điểm

curr += c[x[k-1]][place[y]]; //Tăng chi phí di chuyển

if( k + 1 == leng ){ //Nếu đã đi hết tất cả số điểm mong muốn

if (curr + c[place[y]][place[leng]] < best){ //Nếu chi phí nhỏ hơn chi phí nhỏ nhất

best = curr + c[place[y]][place[leng]]; //Lưu lại chi phí nhỏ nhất

else

if (curr + cmin * (leng - k - 1) < best ) process(k + 1); //Nếu chưa tìm được
chi phí nhỏ nhất, tìm thành phố tiếp theo

curr -= c[x[k-1]][place[y]]; //Trả lại chi phí trước đó

x[k] = 0; //Bỏ đánh dấu địa điểm

//In ra chi phí nhỏ nhất

void print() {

if (best == INT_MAX) best = 0; //Nếu không có đường đi thì in ra 0

cout<<best<<endl; //In ra chi phí nhỏ nhất

int main() {

int n, r; //Số địa điểm n và số người r

cin >> n >> r; //Nhập giá trị của n, r

string person[r + 1]; //String lưu lại địa điểm từng người muốn đi

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

//Nhập giá trị cho ma trận chi phí di chuyển c

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

for ( int j = 1 ; j <= n; j++){

cin>>c[i][j]; //Nhập chi phí di chuyển từ i đến j

if (c[i][j] != 0) //Nếu có đường đi từ i tới j

cmin = (cmin > c[i][j])? c[i][j]:cmin; //Lưu lại chi phí đi lại nhỏ nhất giữa hai thành phố
ij

for (int j = 0; j <= r; j++) { //Duyệt theo từng người

getline(cin, person[j]); //Lưu lại địa điểm từng người muốn đi

for (int j = 1; j <= r; j++){ //Duyệt theo từng người

//Cắt chuỗi chuỗi person[j] thành từng số và lưu lại vào vector a

stringstream ss;

ss<<person[j];

vector<int> a;

while(!ss.eof()){

int x;

ss >> x;

a.push_back(x);

leng = a.size() - 1; //Lưu lại số địa điểm muốn đi

for(int i = 0; i <= leng; i++){ //Duyệt theo từng địa điểm

place[i] = a[i]; //Lưu lại từng địa điểm muốn đi

init(); //Đặt lại dữ liệu

process(1); //Tìm chi phí nhỏ nhất

print(); //In ra kết quả

return 0;
IT3040 – 2023.1 – Mã lớp TH: 732826
Trương Hoàng Phú - 20215628

//Truong Hoang Phu 20215628

Bài tập 12: Đếm đường đi


Cho đồ thị vô hướng G, hãy đếm số đường đi đi qua k cạnh và không đi qua
đỉnh nào quá một lần.

Hình 58 Đề bài bài 12

Hình 59 Code bài 12 (1)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 60 Code bài 12 (2)

Hình 61 Code bài 12 (3)

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

Hình 62 Kết quả bài 12

//Truong Hoang Phu 20215628

/*

Bài tập 12: Đếm đường đi

Cho đồ thị vô hướng G, hãy đếm số đường đi đi qua k cạnh và không đi qua đỉnh nào quá một lần.

*/

#include<bits/stdc++.h>

using namespace std;

const int MAX = 100;

int n, k; //Số đỉnh và số đỉnh đi qua

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

int m; //Số cạnh của đồ thị

vector<vector<int> > vt; //Vector lưu các cạnh của đồ thị

int x[MAX]; //Mảng lưu các đỉnh đã thăm

bool visited[MAX]; //Mảng đánh dấu các đỉnh đã thăm

int res; //Số đường đi hợp lệ

//Hàm nhập dữ liệu //Truong Hoang Phu 20215628

void input(){

cin >> n >> k; //Nhập giá trị của n và k

cin >> m; //Nhập giá trị của m

vt.resize(n+1); //Đặt kích thước vector lưu cạnh theo đỉnh là n+1

for(int i=0; i<m; i++){ //Duyệt từng cạnh nhập vào

int tmp1, tmp2; //Khai báo cặp đỉnh

cin >> tmp1 >> tmp2; //Nhập cặp đỉnh

vt[tmp1-1].push_back(tmp2-1); //Đỉnh tmp1 kề với đỉnh tmp2

vt[tmp2-1].push_back(tmp1-1); //Đỉnh tmp2 kề với đỉnh tmp1

for(int i=0; i<n; i++){ //Duyệt từng đỉnh

visited[i] = false; //Đánh dấu đỉnh chưa thăm

res = 0; //Gán res = 0

//Hàm kiểm tra xem có đường đi từ a đến i không //Truong Hoang Phu 20215628

bool check(int a, int i){

if(a == 0) return true; //Nếu a = 0 trả về true

if(visited[i]) return false; //Nếu đã thăm đỉnh i trả về false

int index = 0; //index đếm số đường có thể đi

for(int j=0; j<vt[x[a-1]].size(); j++){ //Duyệt từng đỉnh kề với a

IT3040 – 2023.1 – Mã lớp TH: 732826


Trương Hoàng Phú - 20215628

if(i == vt[x[a-1]][j]) index++; //Nếu có đỉnh kề thì tăng giá trị index

if(index == 0) return false; //Nếu không có đường thì trả về false

return true; //Trả về true

//Quay lui tìm đường đi //Truong Hoang Phu 20215628

void TRY(int a){

for(int i=0; i<n; i++){ //Duyệt từng đỉnh

if(check(a, i)){ //Nếu kiểm tra hợp lệ

visited[i] = true; //Đánh dấu đỉnh đã thăm

x[a] = i; //Lưu đỉnh đã thăm

if(a == k) res++; //Nếu đã qua k cạnh thì tăng biến đếm

else TRY(a+1); //Nếu không thì gọi đệ quy tìm đường khác

visited[i] = false; //Bỏ đánh dấu đỉnh đã thăm

int main(){

input(); //Nhập dữ liệu

TRY(0); //Gọi hàm quay lui

cout << res / 2; //In ra res/2 do là đồ thị vô hướng nên có lặp

//Truong Hoang Phu 20215628

IT3040 – 2023.1 – Mã lớp TH: 732826

You might also like