Đề thi học sinh giỏi môn Tin học tỉnh Yên Bái năm học 2019-2020 (THCS)

Đề thi học sinh giỏi

Đề 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 ab 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ố ab (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

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’‘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‘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 nm. 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 nm 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 openreadline, lưu số lượng đội và điểm số của các đội vào biến nscores.
  • Tìm điểm số cao nhất của các đội bằng hàm max và lưu vào biến max_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ách winners.
  • Ghi kết quả ra file TRAOGIAI.OUT bằng hàm openwrite. Ghi số lượng đội có điểm số cao nhất bằng hàm len, và ghi danh sách số hiệu của các đội đó bằng hàm join.

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ến nscores.
  • 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ến max_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 vector winners.
  • Ghi kết quả ra file TRAOGIAI.OUT bằng hàm ofstream<<. 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ến nscores.
  • 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ến max_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ảng winners.
  • Ghi kết quả ra file TRAOGIAI.OUT bằng hàm rewritewriteln. 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:

  1. Đọc dữ liệu từ file vào bằng hàm freopen và lưu vào hai biến n và m.
  2. 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.
  3. Gán dp[0] = 1 và dp[1] = 2 để bắt đầu tính toán.
  4. 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.
  5. 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.
  6. 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ặc resetrewrite 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.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *