| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | APIO 2026 — APIOBike | 2600 (p) | 3.0s | 2G |
| 2 | APIO 2026 — Navigation | 2400 (p) | 1.0s | 1G |
| 3 | APIO 2026 — Scallion Pancake Party | 2600 (p) | 1.0s | 2G |
APIOBike là một dịch vụ chia sẻ xe đạp mới được ra mắt tại thành phố APIO. Một vài trạm được lắp đặt khắp thành phố, giúp cho người dùng có thể mượn hoặc trả xe ở bất kỳ trạm nào. Bởi sự tiện dụng và chi phí thấp, nó đã nhanh chóng trở thành phương tiện di chuyển quan trọng nhất trong thành phố APIO. Tuy nhiên, APIOBike đã gặp phải một vấn đề thường gặp của tất cả các hãng dịch vụ chia sẻ xe: sự mất cân bằng giữa tỷ lệ mượn và trả ở những trạm khác nhau. Kết quả là một số trạm có ít xe đạp, làm cho cư dân xung quanh không thể mượn xe; một số trạm lại có quá nhiều xe, những xe thừa mà người dân xung quanh không cần.
Để giải quyết vấn đề này, APIOBike lên kế hoạch điều động một xe tải tái cân bằng mỗi đêm để phân bổ lại xe đạp giữa các trạm, đảm bảo mỗi trạm đều duy trì số lượng xe đạp phù hợp. Thành phố APIO có toàn bộ \(N\) trạm, đánh số \(0, 1, \ldots, N-1\). Thông qua quan sát, APIOBike nhận ra rằng mỗi tối, số lượng xe đạp ở trạm \(i\) luôn có giá trị \(A[i]\), và không ai mượn hoặc trả xe vào buổi tối. Công ty muốn có đúng \(B[i]\) xe ở trạm \(i\) vào mỗi sáng.
Giữa \(N\) trạm, có \(N-1\) con đường được dành cho xe tải tái cân bằng. Mỗi con đường nối giữa hai trạm khác nhau, và xe tải chỉ sử dụng những con đường này để di chuyển. Mỗi con đường có độ dài là một đơn vị. Mạng lưới trạm là liên thông, đảm bảo rằng xe tải có thể di chuyển giữa bất kỳ cặp trạm nào. Mỗi đêm, APIOBike phải điều động một xe tải tái cân bằng để đảm bảo trạm \(i\) có đúng \(B[i]\) xe. Xe tải này có thể bắt đầu ở bất kỳ trạm nào và kết thúc đường đi của nó ở bất kỳ trạm nào.
Xe tải này là rỗng khi bắt đầu quá trình cân bằng. Bất cứ khi nào xe tải ở tại một trạm, người lái xe có thể bốc bất kỳ số lượng xe đạp nào từ trạm lên xe tải, hoặc dỡ bất kỳ số lượng xe đạp nào từ xe tải xuống trạm. Xe tải và các trạm không có giới hạn sức chứa cho xe đạp nhưng số lượng xe đạp ở bất kỳ địa điểm nào phải không bao giờ xuống dưới không. Công ty muốn xác định khoảng cách di chuyển tối thiểu có thể để hoàn thành việc tái cân bằng và chiến lược tương ứng.
Bạn cần xây dựng hàm sau (khai báo trong bike.h):
std::pair<std::vector<int>, std::vector<long long>>
find_rebalancing_strategy(int N,
std::vector<int> A,
std::vector<int> B,
std::vector<int> U,
std::vector<int> V)
Tham số:
Hàm này được gọi tối đa 150 000 lần với mỗi trường hợp thử nghiệm.
Giá trị trả về:
Hàm này cần trả về một cặp mảng \((X, Y)\) có độ dài bằng nhau là \(k+1\), biểu thị một chiến lược tái cân bằng:
Một chiến thuật tái cân bằng hợp lệ \((X, Y)\) với khoảng cách di chuyển \(k\) phải thỏa mãn những điều kiện sau:
find_rebalancing_strategy không vượt quá \(300\,000\) với mỗi trường hợp thử nghiệm.Ở đây, \(T\) là số lần gọi hàm find_rebalancing_strategy, và \(\sum N\) là tổng các \(N\) qua tất cả lời gọi đến hàm find_rebalancing_strategy.
Tính chất P: Với mỗi \(0 \le i < N-1\), \(U[i] = i\) và \(V[i] = i+1\). Với mỗi \(0 \le i < N\), \(A[i] \ne B[i]\).
Ví dụ 1
1
4
10 1 5 0
10 0 3 3
0 1
1 2
1 3
2
2 1 3
-2 -1 3
Có \(N = 4\) trạm ở thành phố APIO. Ban đầu, các trạm có \(A = [10, 1, 5, 0]\) xe, và mục tiêu là có \(B = [10, 0, 3, 3]\) xe ở mỗi trạm.
Xe tải tái cân bằng bắt đầu ở trạm 2 và thực hiện các bước:
Tổng khoảng cách di chuyển là 2. Có thể chứng minh rằng chiến lược này đạt được khoảng cách tối thiểu.
Ví dụ 2
1
5
3 0 1 2 2
2 2 1 3 0
2 0
2 4
2 3
2 1
6
0 2 1 2 4 2 3
-1 -1 2 0 -2 1 1
Có \(N = 5\) trạm ở thành phố APIO. Ban đầu, các trạm có \(A = [3, 0, 1, 2, 2]\) xe, và mục tiêu là có \(B = [2, 2, 1, 3, 0]\) xe ở mỗi trạm.
Xe tải tái cân bằng bắt đầu từ trạm 0 và thực hiện các bước sau:
Tổng khoảng cách di chuyển là 6. Các chiến thuật hợp lệ khác với khoảng cách 6 cũng được xem là đúng đắn.
Ví dụ 3
1
4
3 0 5 0
2 2 3 1
0 1
1 2
2 3
5
2 1 0 1 2 3
-1 1 -1 1 -1 1
Có \(N = 4\) trạm ở thành phố APIO. Ban đầu, các trạm có \(A = [3, 0, 5, 0]\) xe, và mục tiêu là có \(B = [2, 2, 3, 1]\) xe ở mỗi trạm. Các trạm tạo thành một đường thẳng: \(0 - 1 - 2 - 3\).
Một lời giải tối ưu là \(X = [2, 1, 0, 1, 2, 3]\) và \(Y = [-1, 1, -1, 1, -1, 1]\). Tổng khoảng cách di chuyển là 5. Ví dụ này thỏa mãn ràng buộc của subtask 2 và 3. Các chiến thuật hợp lệ khác cũng được xem là đúng đắn.
Đây là bài toán dạng Batch với signature grader (bike.h). Hàm find_rebalancing_strategy của bạn sẽ được gọi tối đa 150 000 lần trong một test case.
Nếu mảng trả về \(X\) và \(Y\) có độ dài chính xác là \(k^* + 1\), trong đó \(k^*\) là khoảng cách di chuyển tối thiểu có thể, nhưng \((X, Y)\) không phải là một chiến lược hợp lệ, bạn sẽ nhận được 50% điểm số của subtask đó.
Đài Loan có mật độ núi cao dày đặc, với hơn 250 đỉnh núi cao hơn 3.000 mét. A-Ming dự định xây dựng mạng lưới robot vận chuyển hàng hóa tự động bằng cáp treo ở Dải núi Trung tâm của Đài Loan để vận chuyển bưu kiện giữa các làng mạc vùng sâu vùng xa.
Trong kế hoạch của A-Ming, mỗi mạng lưới bao gồm \(N\) nút, được đánh số từ \(0\) đến \(N - 1\). Trong số các nút này, chính xác \(K = 6\) nút là các trạm điện và \(N - K\) nút còn lại là các làng. Các nút được kết nối bằng \(N - 1\) dây cáp hai chiều, được đánh số từ \(0\) đến \(N - 2\). Với mỗi \(i\) (\(0 \le i \le N - 2\)), dây cáp \(i\) kết nối các nút \(U[i]\) và \(V[i]\). Mỗi dây cáp kết nối hai nút khác nhau, và mỗi cặp nút được kết nối bởi tối đa một dây cáp. Đảm bảo rằng giữa hai nút bất kỳ đều có thể di chuyển thông qua các dây cáp trong mạng.
Khoảng cách giữa hai nút \(a\) và \(b\) được ký hiệu là \(d(a, b)\) và được định nghĩa như sau:
Ta nói rằng hệ số phân nhánh của mạng ít nhất là \(\delta\) nếu mỗi nút trong mạng được kết nối với chính xác \(1\) hoặc ít nhất \(\delta\) dây cáp. A-Ming biết một số nguyên dương \(B\) mà hệ số phân nhánh của mạng ít nhất là \(B\).
A-Ming đã chuẩn bị 100 loại dây cáp khác nhau, được đánh số từ \(0, 1, \ldots, 99\). Mỗi dây cáp trong mạng được thiết lập từ một trong những loại dây cáp đó.
Các robot sẽ di chuyển dọc theo dây cáp để thực hiện nhiệm vụ giao hàng. A-Ming muốn cài đặt một chương trình điều hướng giúp robot quay trở lại các trạm điện và tự sạc pin. Tuy nhiên, các robot có bộ nhớ cực kỳ hạn chế. Do đó, khi thiết kế chương trình điều hướng, robot chỉ điều hướng dựa trên số lượng trạm điện \(K = 6\), hệ số phân nhánh đảm bảo \(B\) và các loại dây cáp được gắn vào vị trí hiện tại của robot.
Khi một robot muốn di chuyển tại một nút \(u\) là làng được kết nối với hai hoặc nhiều dây cáp, robot trước tiên sẽ quét các dây cáp được kết nối với \(u\) theo một thứ tự bất kỳ. Sau đó, chương trình được cung cấp một danh sách chứa các loại dây cáp theo thứ tự đó. Đối với mỗi dây cáp, chương trình cần đếm số lượng trạm điện sao cho việc đi theo dây cáp đó làm giảm khoảng cách giữa robot và trạm điện.
Cụ thể, gọi \(v_1, \ldots, v_k\) (\(k \ge 2\)) là các nút được kết nối trực tiếp với \(u\) bằng một dây cáp và \(c_i\) (\(1 \le i \le k\)) là loại dây cáp nối nút \(u\) và \(v_i\). Chương trình được cung cấp \(K\), \(B\), và danh sách \(c_1, c_2, \ldots, c_k\). Với mỗi \(i\) (\(1 \le i \le k\)), chương trình phải xác định số lượng trạm điện \(p\) sao cho \(d(v_i, p) < d(u, p)\).
Nhiệm vụ của bạn là xây dựng chiến lược để phân bổ các loại cáp và thiết kế chương trình điều hướng. Điểm số của bài làm của bạn phụ thuộc vào số lượng các loại cáp khác nhau được sử dụng (xem phần Subtask và Chấm điểm để biết thêm chi tiết).
Bạn cần thực hiện hai hàm trong file navigation.h: một hàm để phân bổ loại cáp và một hàm cho chương trình điều hướng của robot. Lưu ý quan trọng: hai hàm này được gọi trong hai tiến trình riêng biệt — hàm construct_network không thể truyền thông tin trực tiếp sang hàm navigate qua biến toàn cục.
Hàm phân bổ loại cáp:
std::vector<int> construct_network(int N, int K, int B,
std::vector<int> U, std::vector<int> V,
std::vector<int> P)
Hàm này cần trả về một mảng \(T\) độ dài \(N - 1\):
Hàm điều hướng của robot:
std::vector<int> navigate(int K, int B, std::vector<int> C)
Hàm điều hướng không được phụ thuộc vào cấu trúc mạng ban đầu; đặc biệt, hệ thống chấm điểm có thể sắp xếp lại tất cả các lệnh điều hướng trên các mạng được xây dựng khác nhau trong cùng một trường hợp thử nghiệm.
Hàm này cần trả về một mảng \(D\):
construct_network không vượt quá \(100\,000\) với mỗi trường hợp thử nghiệm.navigate không vượt quá \(200\,000\) đối với mỗi trường hợp thử nghiệm.Xét kịch bản với \(N = 9\), \(K = 6\), và \(B = 2\).
Cấu trúc của mạng được cho bởi \(U = [0, 0, 0, 2, 2, 2, 2, 7]\), \(V = [1, 2, 3, 4, 5, 6, 7, 8]\). Các trạm điện là \(P = [1, 3, 4, 5, 6, 7]\).
Lời gọi đến tiến trình đầu tiên:
construct_network(9, 6, 2, [0, 0, 0, 2, 2, 2, 2, 7],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 3, 4, 5, 6, 7])
Giả sử A-Ming xây dựng mạng bằng cách trả về:
[0, 10, 1, 2, 3, 4, 5, 5]
Trong mạng này, nút \(0\) (làng) kết nối với nút \(1\) (cáp loại \(0\)), nút \(2\) (cáp loại \(10\)), nút \(3\) (cáp loại \(1\)). Nút \(2\) (làng) kết nối với nút \(0\) (cáp loại \(10\)) và các nút \(4, 5, 6, 7\) (cáp loại \(2, 3, 4, 5\)). Nút \(7\) (trạm điện) kết nối với nút \(8\) (cáp loại \(5\)).
Lời gọi navigate từ nút 0:
navigate(6, 2, [0, 10, 1])
Phân tích khoảng cách:
Số lượng trạm điện có khoảng cách giảm khi đi theo các cáp loại \(0\), \(10\), \(1\) lần lượt là \(1\), \(4\), \(1\). Kết quả trả về:
[1, 4, 1]
Lưu ý: hàm navigate cũng có thể được gọi cho các hoán vị khác của \(C\). Ví dụ, navigate(6, 2, [1, 0, 10]) cũng là một lời gọi hợp lệ cho nút \(0\), và hàm cần trả về [1, 1, 4].
Lời gọi navigate từ nút 2:
navigate(6, 2, [10, 2, 3, 4, 5])
Kết quả trả về:
[2, 1, 1, 1, 1]
Giải thích: Đi theo cáp loại \(10\) (về phía nút \(0\)) làm giảm khoảng cách đến \(2\) trạm điện (nút \(1\) và nút \(3\)). Đi theo mỗi cáp loại \(2, 3, 4, 5\) (về phía các nút \(4, 5, 6, 7\)) đều làm giảm khoảng cách đến đúng \(1\) trạm điện tương ứng.
Trong mạng này, hàm navigate sẽ không bao giờ được gọi cho các nút khác vì: nút \(1, 3, 4, 5, 6, 7\) đều là trạm điện, và nút \(8\) chỉ được nối với duy nhất một dây cáp.
Trong trường hợp thử nghiệm này, các loại dây cáp được sử dụng là \(0, 1, 2, 3, 4, 5\) và \(10\). Do đó, \(S = 11\) được dùng để tính điểm.
Trong bất kỳ trường hợp thử nghiệm nào, nếu ít nhất một trong các điều kiện sau xảy ra, điểm số sẽ là \(0\) (thông báo Output isn't correct):
construct_network không hợp lệ.navigate không chính xác.Trái lại, gọi \(S\) là số nguyên nhỏ nhất lớn hơn tất cả các số trong mọi mảng \(T\) được trả về từ mỗi lệnh gọi construct_network. Nói cách khác, \(S\) là số nguyên nhỏ nhất sao cho tất cả các mạng được xây dựng chỉ sử dụng các loại cáp \(0, 1, \ldots, S - 1\).
Điểm của bạn cho mỗi subtask phụ thuộc vào \(S\) như sau:
| Điều kiện | Subtask 1 | Subtask 2 | Subtask 3 và 4 | Subtask 5 |
|---|---|---|---|---|
| \(100 < S\) | \(0\) | \(0\) | \(0\) | \(0\) |
| \(16 \le S \le 100\) | \(2\) | \(2\) | \(12 - \log_2 S\) | \(24 - 2\log_2 S\) |
| \(10 \le S \le 15\) | \(2\) | \(4\) | \(16 - 0.5S\) | \(32 - S\) |
| \(7 \le S \le 9\) | \(2\) | \(6\) | \(21 - S\) | \(42 - 2S\) |
| \(S = 6\) | \(2\) | \(10\) | \(15\) | \(30\) |
| \(S = 5\) | \(6\) | \(14\) | \(17.5\) | \(40\) |
| \(S \le 4\) | \(6\) | \(14\) | \(20\) | \(40\) |
Đặc biệt, trong Subtask 1, 2 và 5, bạn sẽ nhận được toàn bộ số điểm nếu \(S \le 5\), và trong Subtask 3 và 4, bạn sẽ nhận được toàn bộ số điểm nếu \(S \le 4\).
Bohan đang tổ chức một bữa tiệc. Vì anh ấy rất thích bánh hành lá, nên anh ấy quyết định mua chúng từ cửa hàng gần đó. Cửa hàng bán \(N\) loại bánh hành lá với các hương vị đôi một khác nhau, được đánh số từ \(0\) đến \(N-1\). Bohan quyết định mỗi loại sẽ mua \(N\) bánh hành lá, tổng cộng là \(N^2\) bánh hành lá. Mỗi bánh hành lá được chia thành \(K\) lát giống hệt nhau và cho vào một túi. Các túi được đánh số từ \(0\) đến \(N^2 - 1\). Gọi \(F[i]\) là hương vị bánh hành lá của túi \(i\).
Trong bữa tiệc, Bohan mời tất cả các khách cùng chơi một trò chơi. Trò chơi diễn ra như sau:
Đầu tiên, Bohan chọn \(N\) khách và đưa họ vào các phòng được đánh số \(0, 1, \ldots, N-1\) sao cho mỗi phòng chỉ có đúng một khách. Những khách còn lại sẽ ở ngoài cho đến khi trò chơi kết thúc. Tất cả \(N\) phòng đều trông giống hệt nhau, vì vậy khách không thể biết mình đang ở phòng nào.
Tiếp theo, với mỗi phòng \(i\) (\(0 \le i < N\)), Bohan vào phòng \(i\) và bí mật nói cho khách biết một số nguyên \(P[i]\), biểu thị cho một hương vị bị cấm. Anh ta có thể nói hoặc không nói cho khách biết họ đang ở phòng nào. Bohan đảm bảo rằng \([P[0], P[1], \ldots, P[N-1]]\) là một hoán vị của \([0, 1, \ldots, N-1]\).
Sau đó, có \(N\) vòng. Trong vòng thứ \(i\), Bohan lần lượt mang các túi \(0, 1, \ldots, N^2 - 1\) theo thứ tự vào phòng \(i-1\). Khi khách ở phòng \(i-1\) nhận được túi \(j\), họ sẽ biết:
Trước khi nhận túi tiếp theo, khách ở phòng \(i-1\) phải quyết định ăn bao nhiêu lát từ túi hiện tại. Số lát họ có thể ăn phụ thuộc vào tình huống:
Lưu ý rằng khách không biết trước dãy \(F[0], F[1], \ldots, F[N^2-1]\).
Sau tất cả \(N\) vòng, khách bên ngoài sẽ được xem dãy các túi. Khi nhìn thấy các túi, họ sẽ biết hương vị bánh hành lá và số lượng lát còn lại trong mỗi túi. Với thông tin này, họ phải xác định giá trị của \(P[0], P[1], \ldots, P[N-1]\).
Khách mời được phép trao đổi trước khi trò chơi bắt đầu. Họ cũng biết trước giá trị của \(N\) và \(K\). Mục tiêu của bạn là thực hiện một chiến lược sao cho khách mời bên ngoài luôn có thể xác định chính xác giá trị của \(P[0], P[1], \ldots, P[N-1]\).
Đây là bài toán giao tiếp hai tiến trình (communication task). Bạn cần cài đặt ba hàm trong file party.h.
Hai hàm sau dành cho khách ở các phòng \(0, 1, \ldots, N-1\):
void init(int N, int K, int p, int r)
Giả sử khách đang ở phòng \(i\).
N: số lượng hương vị bánh hành lá.K: số lát bánh hành lá của mỗi loại trước khi trò chơi bắt đầu.p \(= P[i]\): hương vị bị cấm ăn trong phòng \(i\).r \(= i\). Nếu không, r \(= -1\).int strategy(int b, int f, int s)
Giả sử khách đang ở phòng \(i\).
b: số hiệu túi hiện tại.f \(= F[b]\): hương vị bánh hành lá của túi \(b\).s: số lát bánh còn lại trong túi \(b\).Hàm sau dành cho khách bên ngoài:
std::vector<int> guess(int N, int K, std::vector<int> F, std::vector<int> S)
N: số lượng hương vị bánh hành lá.K: số lát của mỗi loại bánh hành lá trước khi trò chơi bắt đầu.F: một mảng có kích thước \(N^2\), trong đó F[i] là hương vị của bánh hành lá trong túi \(i\).S: một mảng có kích thước \(N^2\), trong đó S[i] là số lát còn lại trong túi \(i\) sau tất cả \(N\) vòng chơi.Mỗi trường hợp thử nghiệm bao gồm \(T\) trò chơi độc lập.
Trong quá trình đánh giá, đối với mỗi trò chơi, sẽ có \(N+1\) tiến trình. Với mỗi \(i\) thỏa \(0 \le i < N\), tiến trình \(i\) đại diện cho khách trong phòng \(i\); tiến trình \(N\) đại diện cho khách bên ngoài. Tiến trình \((i+1)\) bắt đầu sau khi tiến trình \(i\) kết thúc.
Đối với các tiến trình từ \(0\) đến \(N-1\):
init được gọi đúng một lần.strategy được gọi \(N^2\) lần sau hàm init. Đảm bảo rằng đối với lần gọi thứ \(j\), b \(= j - 1\).Đối với tiến trình \(N\):
guess được gọi đúng một lần.Trình chấm có thể xen kẽ các tiến trình từ các trò chơi khác nhau, nhưng đảm bảo rằng thứ tự tương đối của các tiến trình trong mỗi trò chơi riêng lẻ được bảo toàn.
init được gọi lần đầu tiênXét tình huống trong đó \(T = 1\) và \(N = 2\), \(K = 2\), \(P = [1, 0]\), \(F = [1, 0, 0, 1]\) cho một trò chơi trong trường hợp thử nghiệm.
Gọi \(S[i]\) là số lát bánh còn lại trong túi \(i\). Ban đầu, \(S = [2, 2, 2, 2]\).
Giả sử các khách xác định chiến lược dưới đây trước khi trò chơi bắt đầu:
Vòng 1 (phòng 0, \(P[0] = 1\)): Trình chấm gọi init(2, 2, 1, -1), sau đó:
| Gọi hàm | Giá trị trả về |
|---|---|
strategy(0, 1, 2) |
0 |
strategy(1, 0, 2) |
2 |
strategy(2, 0, 2) |
1 |
strategy(3, 1, 2) |
0 |
Lần gọi thứ nhất và thứ tư phải trả về \(0\) vì \(P[0] = F[0] = F[3] = 1\). Sau vòng 1, \(S = [2, 0, 1, 2]\).
Vòng 2 (phòng 1, \(P[1] = 0\)): Trình chấm gọi init(2, 2, 0, -1), sau đó:
| Gọi hàm | Giá trị trả về |
|---|---|
strategy(0, 1, 2) |
2 |
strategy(1, 0, 0) |
0 |
strategy(2, 0, 1) |
0 |
strategy(3, 1, 2) |
1 |
Lần gọi thứ hai và thứ ba phải trả về \(0\) vì \(P[1] = F[1] = F[2] = 0\). Sau vòng 2, \(S = [0, 0, 1, 1]\).
Khách bên ngoài: Trình chấm gọi:
| Gọi hàm | Giá trị trả về |
|---|---|
guess(2, 2, [1, 0, 0, 1], [0, 0, 1, 1]) |
[1, 0] |
Các vị khách bên ngoài đã đoán đúng hoán vị. Do đó, trường hợp thử nghiệm này được đánh giá là đúng.
Lưu ý rằng phương pháp chiến lược trong ví dụ này không phải lúc nào cũng giúp các vị khách bên ngoài đoán đúng hoán vị — đây chỉ là minh họa cơ chế hoạt động, không phải lời giải đúng cho bài toán.
Trình chấm mẫu chỉ hỗ trợ một trò chơi cho mỗi trường hợp thử nghiệm.
Định dạng đầu vào của trình chấm mẫu:
N K
P[0] P[1] ... P[N-1]
F[0] F[1] ... F[N*N-1]
reveal
reveal bằng 0 hoặc 1.reveal bằng 0, trình chấm sẽ coi như Bohan không nói số phòng của ai (\(r = -1\) cho mọi khách).reveal bằng 1, trình chấm sẽ coi như Bohan nói số phòng của mọi người (\(r = i\) cho khách ở phòng \(i\)).Nếu vector được trả về bởi guess khớp với \([P[0], P[1], \ldots, P[N-1]]\), trình chấm mẫu sẽ in ra Accepted. Ngoài ra, trình chấm sẽ in ra các lệnh gọi hàm đã thực hiện để phục vụ mục đích gỡ lỗi.