Hướng dẫn giải của MOD


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.

Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.

Bạn phải đăng nhập để mở lời giải này.

Đăng nhập

Tác giả: Hiếu Nguyễn, thanhdoan, LamThanhVu, nquang2909

Editorial for mod: MOD

Hiểu bài toán

Bài toán yêu cầu trích xuất ba chữ số cuối cùng của số nguyên N (chữ số hàng trăm, hàng chục và hàng đơn vị). Nếu số N có ít hơn 3 chữ số, cần thêm các số 0 ở phía trước để luôn in ra đúng 3 ký tự. Ví dụ: N = 12 trả về '012', N = -12345 trả về '345'.

Các cách tiếp cận

Cách Phép chia và lấy dư (Số học)
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;
    scanf("%d", &n);
    n = abs(n);
    printf("%03d", n % 1000);
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Phương pháp này sử dụng các phép toán số học. Đầu tiên, dùng hàm abs() để lấy giá trị tuyệt đối của N, loại bỏ dấu âm. Sau đó, sử dụng phép toán modulo 1000 (n % 1000) để lấy phần dư khi chia cho 1000, chính là 3 chữ số cuối cùng. Cuối cùng, dùng format string %03d để in ra số, tự động thêm các số 0 ở phía trước nếu cần thiết để đủ 3 chữ số.

Cách Xử lý chuỗi ký tự
#include <stdio.h>
#include <string.h>

int main() {
    char s[8];
    scanf("%s", s);
    int len = strlen(s);
    char a[4];
    int k = 0;
    // Lấy 3 ký tự cuối
    for (int i = len - 3; i <= len - 1; i++) {
        a[k++] = s[i];
    }
    a[3] = '\0';
    printf("%s", a);
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Phương pháp này coi số N là một chuỗi ký tự. Đọc N vào dưới dạng chuỗi, xác định độ dài của chuỗi. Sau đó, trích xuất 3 ký tự cuối cùng của chuỗi và in ra. Cách này xử lý trực quan nhưng cần lưu ý xử lý các ký tự dấu '-' nếu độ dài chuỗi nhỏ hơn 3 (tuy nhiên trong các test case của bài này, phép toán số học hoặc substring 3 ký tự cuối thường hoạt động đúng do yêu cầu in 3 số cuối cùng).

Cách Phép chia và lấy dư (Cải tiến)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main() {
    int x;
    scanf("%d", &x);
    int dv = abs(x % 10);
    int chuc = abs((x / 10) % 10);
    int tram = abs((x / 100) % 10);
    printf("%d%d%d", tram, chuc, dv);
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Đây là biến thể của phương pháp số học. Thay vì lấy dư cả nghìn, ta tách từng số đơn vị, chục và trăm bằng cách chia và lấy dư liên tiếp. x % 10 lấy số hàng đơn vị, (x / 10) % 10 lấy số hàng chục, (x / 100) % 10 lấy số hàng trăm. Mỗi lần lấy đều dùng abs() để đảm bảo giá trị dương. Cuối cùng in kết quả. Phương pháp này không cần format string %03d nhưng logic hơi dài dòng hơn.

Phân tích độ phức tạp

Cách tiếp cận Time Space Tên
1 O(1) O(1) Phép chia và lấy dư (Số học)
2 O(1) O(1) Xử lý chuỗi ký tự
3 O(1) O(1) Phép chia và lấy dư (Cải tiến)

Bài học kinh nghiệm

  • Sử dụng abs() để xử lý số âm là bước quan trọng trước khi thực hiện các phép tính.
  • Phép toán modulo (%) là công cụ hiệu quả nhất để cô lập các chữ số cuối cùng.
  • Format string %03d là cách ngắn gọn nhất để xử lý yêu cầu in thêm số 0 ở đầu.

Lỗi thường gặp

  • Quên xử lý số âm dẫn đến in ra kết quả sai (ví dụ -123 % 1000 = -23).
  • Lỗi tràn bộ nhớ khi khai báo mảng ký tự quá nhỏ nếu N có số lượng chữ số lớn.
  • Sai logic khi trích xuất chuỗi đối với các số nhỏ hơn 3 chữ số nếu không kiểm tra độ dài kỹ lưỡng.

Bình luận

Please read the guidelines before commenting.


Không có bình luận tại thời điểm này.