Nội dung chính
Đề thi học sinh giỏi bậc THCS
TỔNG QUAN ĐỀ THI
|
Tên bài |
File chương trình |
File dữ liệu vào |
File dữ liệu ra |
Bài 1 |
Số tốt hơn |
SOTOT.* |
SOTOT.INP |
SOTOT.OUT |
Bài 2 |
Trao giải |
TRAOGIAI.* |
TRAOGIAI.INP |
TRAOGIAI.OUT |
Bài 3 |
Tính điểm |
TINHDIEM.* |
TINHDIEM.INP |
TINHDIEM.OUT |
Bài 4 |
Dãy nhị phân |
NHIPHAN.* |
NHIPHAN.INP |
NHIPHAN.OUT |
Dấu * là đại diện cho phần mở rộng, được thay bằng PAS hoặc CPP tùy theo ngôn ngữ lập trình được sử dụng là Pascal hay C++.
Bài 1: (7,0 điểm) Số tốt hơn
Số nguyên a được coi là tốt hơn số nguyên b nếu tổng các chữ số của a lớn hơn tổng các chữ số của b. Với hai số có tổng các chữ số bằng nhau, số bé hơn được coi là tốt hơn.
Yêu cầu: Hãy cho biết số nguyên nào tốt hơn.
Dữ liệu vào: File SOTOT.INP ghi hai số nguyên a và b cách nhau một khoảng trắng (0 ≤ a, b ≤ 109).
Dữ liệu ra: File SOTOT.OUT ghi số nguyên tốt hơn trong hai số a và b (Nếu hai số a, b bằng nhau thì ghi ra số -1).
Ví dụ:
SOTOT.INP |
SOTOT.OUT |
124 123 |
124 |
111 3 |
3 |
10 10 |
-1 |
Bài 2: (6,0 điểm) Trao giải
Có n đội tham gia trại hè “Tin học vui”, các đội được đánh số hiệu lần lượt từ 1 đến n (2 ≤ n ≤ 106). Qua các vòng thi, mỗi đội đạt được số điểm là ai (0 ≤ ai ≤ 106, 1 ≤ i ≤ n).
Yêu cầu: Hãy giúp Ban tổ chức trại hè tính số lượng đội có điểm số cao nhất và chỉ ra số hiệu của các đội đó.
Dữ liệu vào: File TRAOGIAI.INP gồm:
– Dòng đầu tiên: Ghi số nguyên dương n.
– Dòng thứ hai: Ghi n số nguyên dương lần lượt là điểm đạt được ai của đội thứ i (1 ≤ i ≤ n), mỗi số được ghi cách nhau một khoảng trắng.
Dữ liệu ra: File TRAOGIAI.OUT gồm:
– Dòng đầu tiên: Ghi số nguyên tương ứng là số lượng đội có điểm số cao nhất.
– Dòng thứ hai: Ghi các số nguyên tương ứng là hiệu số của các đội có điểm số cao nhất, mỗi số cách nhau một khoảng trắng.
Ví dụ:
TRAOGIAI.INP |
TRAOGIAI.OUT |
5 10 15 10 9 15 |
2 2 5 |
Bài 3: (4,0 điểm) Tính điểm
Trong cuộc thi “Tin học nhanh”, người chơi phải trả lời liên tiếp các câu hỏi của MC, nếu trả lời đúng, máy tính sẽ lưu bằng ký tự ‘Y’ hoặc ‘y’ (Đúng), nếu trả lời sai, máy tính sẽ lưu kí tự ‘N’ hoặc ‘n’ (Sai). Khi người chơi trả lời đúng, MC sẽ đưa ra câu hỏi tiếp theo khó hơn câu trước, còn khi trả lời sai, MC sẽ đưa ra câu hỏi mới dễ hơn.
Sau khi thi xong, kết quả của mỗi người chơi là một xâu S gồm các ký tự ‘Y’, ‘y’, ‘N’ và ‘n’. Điểm số của mỗi người chơi sẽ được tính như sau: Với các câu trả lời sai người chơi không được điểm, với mỗi câu trả lời đúng người chơi nhận được điểm bằng số lần trả lời đúng liên tiếp từ câu trả lời này trở về trước đó. Ví dụ, nếu kết quả xâu S là ‘YyNNYnNYYY’, thì điểm số của người chơi được tính là 1+2+0+0+1+0+0+1+2+3 = 10.
Yêu cầu: Cho xâu kết quả S, hãy tính điểm của người chơi.
Dữ liệu vào: File TINHDIEM.INP ghi một xâu ký tự S (1 ≤ độ dài của S ≤ 255).
Dữ liệu ra: File TINHDIEM.OUT ghi một số nguyên duy nhất tương ứng là điểm số mà người chơi đạt được.
Ví dụ:
TINHDIEM.INP |
TINHDIEM.OUT |
Giải thích |
YNnYNyYYyYY |
14 |
1+0+0+1+0+1+2+3+4+5+6 = 23 |
Bài 4: (3,0 điểm) Dãy nhị phân
Một tập S chứa tất cả các dãy bit 0, 1 có độ dài bằng n, trong đó không có hai bit 1 nào kề nhau (1 ≤ n ≤ 50). Tập S được sắp xếp tăng dần theo chiều tăng dần của số nguyên tương ứng mà dãy bit biểu diễn.
Yêu cầu: Cho hai số nguyên n và m. Hãy cho biết dãy bit thứ m trong tập S.
Dữ liệu vào: File NHIPHAN.INP gồm hai số nguyên n và m cách nhau một khoảng trắng (m cho đảm bảo có nghiệm).
Dữ liệu ra: File NHIPHAN.OUT ghi dãy bit thứ m tìm được (các bit 0, 1 liền nhau).
Ví dụ:
NHIPHAN.INP |
NHIPHAN.OUT |
Giải thích |
3 2 |
001 |
n = 3; m = 2 Tập S = {000; 001; 010; 100; 101} Dãy bit thứ 2 trong xâu S là: 001 |
Giới hạn: Có 60% số test tương ứng 60% số điểm với n ≤ 30.
Đáp án tham khảo
Bài 1. Số tốt hơn
Chúng ta sẽ thực hiện giải bài toán này với 3 ngôn ngữ lập trình: Python, C++ và Pascal
Python
# Đọc dữ liệu vào từ tệp đầu vào
with open('SOTOT.INP', 'r') as f:
a, b = map(int, f.readline().split())
# Tính tổng các chữ số của a và b
def digit_sum(x):
return sum(map(int, str(x)))
sum_a, sum_b = digit_sum(a), digit_sum(b)
# So sánh tổng các chữ số để xác định số tốt hơn
if sum_a > sum_b:
result = a
elif sum_b > sum_a:
result = b
else:
# Nếu hai số có tổng các chữ số bằng nhau, so sánh hai số để xác định số bé hơn
if a < b:
result = a
elif b < a:
result = b
else:
# Nếu hai số bằng nhau, ghi ra -1
result = -1
# Ghi kết quả vào tệp đầu ra
with open('SOTOT.OUT', 'w') as f:
f.write(str(result))
C++
#include <bits/stdc++.h>
using namespace std;
int digitSum(int x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
int main() {
int a, b;
ifstream inFile("SOTOT.INP");
inFile >> a >> b;
inFile.close();
int sum_a = digitSum(a);
int sum_b = digitSum(b);
int result;
if (sum_a > sum_b) {
result = a;
} else if (sum_b > sum_a) {
result = b;
} else {
if (a < b) {
result = a;
} else if (b < a) {
result = b;
} else {
result = -1;
}
}
ofstream outFile("SOTOT.OUT");
outFile << result << endl;
outFile.close();
return 0;
}
Pascal
#include <bits/stdc++.h>
using namespace std;
int digitSum(int x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
int main() {
int a, b;
ifstream inFile("SOTOT.INP");
inFile >> a >> b;
inFile.close();
int sum_a = digitSum(a);
int sum_b = digitSum(b);
int result;
if (sum_a > sum_b) {
result = a;
} else if (sum_b > sum_a) {
result = b;
} else {
if (a < b) {
result = a;
} else if (b < a) {
result = b;
} else {
result = -1;
}
}
ofstream outFile("SOTOT.OUT");
outFile << result << endl;
outFile.close();
return 0;
}
Bài 2. Trao giải
Python
with open('TRAOGIAI.INP', 'r') as f_in:
n = int(f_in.readline().strip())
scores = list(map(int, f_in.readline().strip().split()))
max_score = max(scores)
winners = [i+1 for i, score in enumerate(scores) if score == max_score]
with open('TRAOGIAI.OUT', 'w') as f_out:
f_out.write(f"{len(winners)}\n")
f_out.write(" ".join(str(winner) for winner in winners))
Giải thích:
- Đầu tiên, đọc dữ liệu vào từ file TRAOGIAI.INP bằng hàm
open
vàreadline
, lưu số lượng đội và điểm số của các đội vào biếnn
vàscores
. - Tìm điểm số cao nhất của các đội bằng hàm
max
và lưu vào biếnmax_score
. - Duyệt qua từng đội, nếu điểm số của đội đó bằng
max_score
thì lưu số hiệu của đội đó vào danh sáchwinners
. - Ghi kết quả ra file TRAOGIAI.OUT bằng hàm
open
vàwrite
. Ghi số lượng đội có điểm số cao nhất bằng hàmlen
, và ghi danh sách số hiệu của các đội đó bằng hàmjoin
.
C++
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main() {
ifstream fin("TRAOGIAI.INP");
int n;
fin >> n;
vector<int> scores(n);
for (int i = 0; i < n; i++) {
fin >> scores[i];
}
fin.close();
int max_score = *max_element(scores.begin(), scores.end());
vector<int> winners;
for (int i = 0; i < n; i++) {
if (scores[i] == max_score) {
winners.push_back(i+1);
}
}
ofstream fout("TRAOGIAI.OUT");
fout << winners.size() << endl;
for (int i = 0; i < winners.size(); i++) {
fout << winners[i] << " ";
}
fout.close();
return 0;
}
Giải thích:
- Đầu tiên, đọc dữ liệu vào từ file TRAOGIAI.INP bằng hàm
ifstream
và lưu số lượng đội và điểm số của các đội vào biếnn
vàscores
. - Tìm điểm số cao nhất của các đội bằng hàm
max_element
và lưu vào biếnmax_score
. - Duyệt qua từng đội, nếu điểm số của đội đó bằng
max_score
thì lưu số hiệu của đội đó vào vectorwinners
. - Ghi kết quả ra file TRAOGIAI.OUT bằng hàm
ofstream
và<<
. Ghi số lượng đội có điểm số cao nhất và danh sách số hiệu của các đội đó.
Pascal
program trao_giai;
var
n, i, max_score: integer;
scores, winners: array of integer;
fin, fout: text;
begin
assign(fin, 'TRAOGIAI.INP');
reset(fin);
readln(fin, n);
setlength(scores, n);
for i := 0 to n - 1 do
read(fin, scores[i]);
close(fin);
max_score := scores[0];
for i := 1 to n - 1 do
if scores[i] > max_score then
max_score := scores[i];
setlength(winners, 0);
for i := 0 to n - 1 do
if scores[i] = max_score then
begin
setlength(winners, length(winners) + 1);
winners[length(winners) - 1] := i + 1;
end;
assign(fout, 'TRAOGIAI.OUT');
rewrite(fout);
writeln(fout, length(winners));
for i := 0 to length(winners) - 1 do
write(fout, winners[i], ' ');
close(fout);
end.
Giải thích:
- Đầu tiên, đọc dữ liệu vào từ file TRAOGIAI.INP bằng hàm
reset
và lưu số lượng đội và điểm số của các đội vào biếnn
vàscores
. - Tìm điểm số cao nhất của các đội bằng cách duyệt từng phần tử của mảng
scores
và lưu vào biếnmax_score
. - Duyệt qua từng đội, nếu điểm số của đội đó bằng
max_score
thì lưu số hiệu của đội đó vào mảngwinners
. - Ghi kết quả ra file TRAOGIAI.OUT bằng hàm
rewrite
vàwriteln
. Ghi số lượng đội có điểm số cao nhất và danh sách số hiệu của các đội đó.
Bài 3. Tính điểm
Python
# mở file đầu vào và đọc xâu S
with open('TINHDIEM.INP', 'r') as f:
S = f.read().strip()
# khởi tạo biến lưu điểm và số lần trả lời đúng liên tiếp
score = 0
consecutive_correct = 0
# duyệt qua từng ký tự trong xâu S
for i in range(len(S)):
# nếu trả lời sai thì reset số lần trả lời đúng liên tiếp
if S[i] == 'N' or S[i] == 'n':
consecutive_correct = 0
# nếu trả lời đúng thì cộng điểm và tăng số lần trả lời đúng liên tiếp lên 1
else:
score += consecutive_correct + 1
consecutive_correct += 1
# mở file đầu ra và ghi điểm vào file
with open('TINHDIEM.OUT', 'w') as f:
f.write(str(score))
Giải thích:
Đầu tiên, chúng ta mở file đầu vào và đọc xâu S vào biến S
.
Sau đó, chúng ta khởi tạo biến score
lưu điểm và biến consecutive_correct
lưu số lần trả lời đúng liên tiếp, ban đầu bằng 0.
Tiếp theo, chúng ta duyệt qua từng ký tự trong xâu S
. Nếu ký tự hiện tại là ‘N’ hoặc ‘n’ (trả lời sai), thì chúng ta reset biến consecutive_correct
về 0. Nếu ký tự hiện tại là ‘Y’ hoặc ‘y’ (trả lời đúng), thì chúng ta cộng điểm bằng số lần trả lời đúng liên tiếp từ câu trả lời này trở về trước đó (biến consecutive_correct
) và tăng biến consecutive_correct
lên 1.
Cuối cùng, chúng ta mở file đầu ra và ghi điểm vào file.
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("TINHDIEM.INP", "r", stdin); // đọc file input
freopen("TINHDIEM.OUT", "w", stdout); // ghi file output
string s;
cin >> s;
int n = s.length();
int cur_score = 0, ans = 0;
for (int i = 0; i < n; i++) {
if (s[i] == 'Y' || s[i] == 'y') {
cur_score++;
ans += cur_score;
} else {
cur_score = 0;
}
}
cout << ans;
return 0;
}
Pascal
var
S: string;
i, j, score: longint;
begin
{Mở file input và output}
assign(input, 'TINHDIEM.INP');
assign(output, 'TINHDIEM.OUT');
reset(input);
rewrite(output);
readln(S); // Đọc xâu kết quả từ file input
score := 0; // Khởi tạo điểm số
{Tính điểm số}
i := 1;
while i <= length(S) do
begin
if (S[i] = 'Y') or (S[i] = 'y') then
begin
j := i - 1;
while (j >= 1) and ((S[j] = 'Y') or (S[j] = 'y')) do
j := j - 1;
score := score + (i - j);
i := i + 1;
end
else
i := i + 1;
end;
writeln(score); // Ghi điểm số vào file output
{Đóng file input và output}
close(input);
close(output);
end.
Bài 4. Dãy nhị phân
Để giải bài toán này, ta có thể sử dụng phương pháp đệ quy để tạo ra tất cả các dãy nhị phân có độ dài n và không có hai bit 1 nào kề nhau. Sau đó, ta sắp xếp các dãy nhị phân theo thứ tự tăng dần của số nguyên tương ứng mà chúng biểu diễn và trả về dãy bit thứ m trong tập S.
Python
# mở file input và output
with open("NHIPHAN.INP", "r") as f:
n, m = map(int, f.readline().split())
with open("NHIPHAN.OUT", "w") as f:
# Tính số dãy bit có độ dài n
f0 = 1
f1 = 1
for i in range(2, n + 1):
f0, f1 = f1, f0 + f1
# Tìm dãy bit thứ m
ans = ""
for i in range(n):
# Số lượng dãy bit có độ dài n - i - 1 bắt đầu bằng 0
cnt0 = f1 if i == 0 else f0 + f1
if m <= cnt0:
ans += "0"
f0, f1 = f0, f1 - f0
else:
ans += "1"
f0, f1 = f1 - f0, f0
m -= cnt0
f.write(ans)
C++
Để giải bài toán trên bằng ngôn ngữ C++, ta sẽ sử dụng hàm freopen để đọc và ghi file. Các bước giải bài toán như sau:
- Đọc dữ liệu từ file vào bằng hàm freopen và lưu vào hai biến n và m.
- Khởi tạo một mảng dp có kích thước bằng n+1 và một mảng pre có kích thước bằng n+1.
- Gán dp[0] = 1 và dp[1] = 2 để bắt đầu tính toán.
- Dùng vòng lặp for để tính giá trị dp[i] bằng cách cộng tổng giá trị dp[j] với j nhỏ hơn i và j chia hết cho 2.
- Dùng vòng lặp while để tìm dãy bit thứ m. Ban đầu ta lưu mảng pre[i] bằng số dư của m cho dp[i-1]. Sau đó, ta lấy giá trị pre[i] chia cho dp[i-2] và gán giá trị này vào m. Lặp lại cho đến khi i = 1.
- Ghi dãy bit thứ m tìm được vào file NHIPHAN.OUT.
#include <bits/stdc++.h>
using namespace std;
int main() {
// Sử dụng hàm freopen để đọc dữ liệu từ file NHIPHAN.INP và ghi kết quả vào file NHIPHAN.OUT
freopen("NHIPHAN.INP", "r", stdin);
freopen("NHIPHAN.OUT", "w", stdout);
int n, m;
cin >> n >> m;
int dp[n+1];
int pre[n+1];
dp[0] = 1;
dp[1] = 2;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
m--; // Chuyển m sang dạng index bắt đầu từ 0
for (int i = n; i >= 1; i--) {
pre[i] = m % dp[i-1];
m /= dp[i-2];
}
for (int i = 1; i <= n; i++) {
cout << pre[i] + 1; // In ra dãy bit (chuyển sang dạng 1-index)
}
return 0;
}
Pascal
program nhiphan;
var
n, m, i, cnt: longint;
f: array[0..51] of int64;
begin
// Mở file input và output
assign(input, 'NHI_PHAN.INP');
assign(output, 'NHI_PHAN.OUT');
reset(input);
rewrite(output);
// Đọc dữ liệu vào
readln(n, m);
// Khởi tạo mảng f
f[0] := 1;
f[1] := 2;
for i := 2 to n do
f[i] := f[i-1] + f[i-2];
// Tìm dãy bit thứ m
cnt := 0;
for i := n downto 1 do
begin
if (m > f[i-1]) then
begin
write('1');
m := m - f[i-1];
cnt := cnt + 1;
end
else
begin
write('0');
if (cnt > 0) then
m := m - f[i+1-cnt];
end;
end;
// Đóng file input và output
close(input);
close(output);
end.
Giải thích các bước giải bài toán trong code:
- Dòng 4: Khai báo biến n, m, i, cnt và mảng f có kích thước 52. Biến n, m lưu giá trị đọc vào từ file input, biến i dùng trong vòng lặp for, biến cnt đếm số lượng bit 1 đã được in ra, mảng f lưu các giá trị Fibonacci.
- Dòng 9-10: Mở file input và output để đọc và ghi dữ liệu.
- Dòng 13: Đọc dữ liệu vào từ file input bằng cách sử dụng lệnh readln.
- Dòng 16-19: Khởi tạo mảng f với f[0] = 1, f[1] = 2 và các giá trị tiếp theo được tính bằng cách cộng hai phần tử liền trước của mảng.
- Dòng 22-31: Tìm dãy bit thứ m bằng cách sử dụng vòng lặp for. Với mỗi giá trị i từ n đến 1, ta kiểm tra nếu m > f[i-1] thì in ra bit 1, giảm m đi f[i-1], tăng cnt lên 1. Ngược lại, in ra bit 0 và giảm m đi f[i+1-cnt] nếu cnt > 0. Điều này là vì nếu có bit 1 được in ra thì ta sẽ bỏ qua hai số Fibonacci liền trước đó (f[i+1-cnt] là số Fibonacci thứ i+1-cnt).
- Dòng 34-35: Đóng file input và output.
Đánh giá độ phức tạp
Có nhiều ý tưởng để giải các bài toán trên, tùy thuộc vào tình huống cụ thể và điều kiện của bài toán. Dưới đây là một số ý tưởng có thể áp dụng:
-
Sử dụng các thuật toán tối ưu hơn để giải quyết bài toán, chẳng hạn như sử dụng thuật toán quy hoạch động để giải bài toán dãy nhị phân, giúp giảm độ phức tạp thời gian của chương trình.
-
Tối ưu hóa lại cách thức đọc và ghi file dữ liệu, chẳng hạn như sử dụng các hàm tương tự như
freopen
trong C++ hoặcreset
vàrewrite
trong Pascal. -
Sử dụng các cấu trúc dữ liệu hiệu quả hơn, chẳng hạn như sử dụng các cấu trúc dữ liệu như Heap, Tree, Hash Table, … để giải quyết bài toán.
-
Tìm cách giải quyết bài toán bằng cách tận dụng các tính chất đặc biệt của bài toán, giúp giảm độ phức tạp thời gian và không gian của chương trình.
Tuy nhiên, việc chọn ý tưởng tốt nhất phụ thuộc vào tình huống cụ thể của bài toán và khả năng của người giải quyết.
Giải bài toán 4 bằng phương pháp quy hoạch động
Python
# Đọc dữ liệu vào từ file NHIPHAN.INP
with open('NHIPHAN.INP', 'r') as f:
n, m = map(int, f.readline().split())
# Tạo mảng dp với n+1 phần tử, ban đầu đều bằng 0
dp = [0] * (n + 1)
# Với các trường hợp cơ bản, ta sẽ lưu giá trị vào dp
dp[1] = 2
if n >= 2:
dp[2] = 3
# Xây dựng các giá trị trong dp từ 3 đến n
for i in range(3, n+1):
dp[i] = dp[i-1] + dp[i-2]
# Mở file NHIPHAN.OUT để ghi dữ liệu ra
with open('NHIPHAN.OUT', 'w') as f:
# Duyệt ngược lại mảng dp để tìm dãy bit thứ m
for i in range(n, 0, -1):
# Nếu m nhỏ hơn hoặc bằng giá trị dp[i-1]
# thì dãy bit thứ m phải bắt đầu bằng 0
if m <= dp[i-1]:
f.write('0')
# Nếu không, thì dãy bit thứ m phải bắt đầu bằng 1
else:
f.write('1')
# Điều chỉnh lại giá trị của m và i để tìm các bit tiếp theo
m -= dp[i-1]
if i == 2:
m -= 1
# Nếu m đã bằng 0 thì không cần duyệt các bit còn lại
if m == 0:
break
C++
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 55;
long long f[MAXN];
int n, m;
void find_ans() {
f[0] = 1, f[1] = 2;
for (int i = 2; i <= n; i++) {
f[i] = f[i - 1] + f[i - 2];
}
string ans = "";
for (int i = n; i >= 1; i--) {
if (m > f[i - 1]) {
ans += '1';
m -= f[i - 1];
}
else {
ans += '0';
}
}
reverse(ans.begin(), ans.end());
ofstream fout("NHIPHAN.OUT");
fout << ans;
fout.close();
}
int main() {
freopen("NHIPHAN.INP", "r", stdin);
freopen("NHIPHAN.OUT", "w", stdout);
cin >> n >> m;
find_ans();
return 0;
}
Pascal
program NHIPHAN;
uses math;
var
n, m: longint;
f: array[0..50, 0..1] of int64; // Khai báo bảng lưu kết quả
res: string;
procedure readInput(); // Hàm đọc dữ liệu vào
var
f: text;
begin
assign(f, 'NHIPHAN.INP');
reset(f);
readln(f, n, m);
close(f);
end;
procedure writeOutput(); // Hàm ghi kết quả ra file
var
f: text;
begin
assign(f, 'NHIPHAN.OUT');
rewrite(f);
write(f, res);
close(f);
end;
procedure solve(); // Hàm giải bài toán
var
i: longint;
begin
// Xử lý trường hợp đặc biệt n = 1
if n = 1 then
begin
if m = 1 then
res := '0'
else
res := '1';
exit;
end;
// Khởi tạo giá trị đầu tiên của bảng
f[1][0] := 1;
f[1][1] := 1;
// Dùng công thức quy hoạch động để tính toán giá trị của các ô còn lại trong bảng
for i := 2 to n do
begin
f[i][0] := f[i - 1][1];
f[i][1] := f[i - 1][0] + f[i - 1][1];
end;
// Xây dựng chuỗi kết quả dựa trên bảng tính toán được
if m > f[n][1] then
begin
res := '-1'; // Trường hợp không tìm thấy kết quả
exit;
end;
for i := n downto 1 do
begin
if m <= f[i - 1][1] then
res := res + '0'
else
begin
res := res + '1';
m := m - f[i - 1][1];
end;
end;
end;
begin
readInput();
solve();
writeOutput();
end.