Hướng dẫn giải của Làm tròn số


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, mufininstinct, tle778047, nguyencongk53e

Hiểu bài toán

Bài toán yêu cầu viết chương trình đọc một số thực từ bàn phím và làm tròn nó về số nguyên gần nhất. Quy tắc làm tròn thông thường được áp dụng: nếu phần thập phân nhỏ hơn 0.5 thì làm tròn xuống, nếu lớn hơn hoặc bằng 0.5 thì làm tròn lên. Với số âm, cần phải xử lý cẩn thận để đảm bảo giá trị tròn về số nguyên gần nhất (ví dụ -100.299 tròn về -100, -100.5 tròn về -100 theo quy tắc gần nhất, hoặc -101 tùy quy ước nhưng bài này tuân theo quy tắc làm tròn toán học chuẩn:远离 0). Tuy nhiên, nhìn vào các solution accepted, dường như tác giả đang sử dụng quy tắc 'round half away from zero' (tức -100.5 sẽ tròn thành -101).

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

Cách Phương pháp cộng/trừ 0.5 và ép kiểu
#include <stdio.h>
#include <stdlib.h>

int main()
{
    double a, kq;
    scanf("%lf", &a);
    if(a > 0) kq = (int)(a + 0.5);
    else kq = (int)(a - 0.5);
    printf("%.0f", kq);
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Đây là cách tiếp cận phổ biến và ngắn gọn nhất. Với số dương, ta cộng thêm 0.5 vào số đó rồi lấy phần nguyên (ép kiểu int). Ví dụ: 5.5 + 0.5 = 6.0 -> (int)6. Với số âm, ta trừ đi 0.5 rồi ép kiểu. Ví dụ: -100.5 - 0.5 = -101.0 -> (int)-101. Hàm printf với %.0f sẽ in ra số nguyên.

Cách Phương pháp kiểm tra phần thập phân
#include <stdio.h>
#include <math.h>
int main(){
    double  a;
    scanf("%lf", &a);
    double x = fabs(a-(int)a);
    if(x>=0.5){
        if(a>0) printf("%d", (int)a + 1);
        else printf("%d", (int)a - 1);
    }
    else printf("%d",(int)a );
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Cách tiếp cận này mô phỏng suy nghĩ của con người rõ ràng hơn. Nó tính toán phần thập phân (a - (int)a). Nếu phần thập phân >= 0.5, nó tăng giá trị lên 1 đơn vị. Tuy nhiên, đoạn code này (và cách làm tròn của C khi ép kiểu số âm) có một điểm đặc biệt: ép kiểu số âm về int thường cắt bỏ phần thập phân (tròn về 0). Ví dụ (int)-100.5 là -100. Do đó, để đạt được -101 (tròn về số xa 0 hơn), tác giả phải trừ đi 1 đơn vị nữa trong nhánh else. Logic này hoạt động đúng với các test case.

Cách Phương pháp ép kiểu trực tiếp (Cẩn thận)
#include <stdio.h>
int main (){
    double a;
    scanf ("%lf", &a);

    if (a >= 0){
        a += 0.5;
    }
    else {
        a -= 0.5;
    }
    printf ("%d", (int)a);
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Đây là biến thể của phương pháp 1, chỉ khác là in ra bằng %d sau khi ép kiểu biến a. Biến a được cập nhật trước khi ép kiểu. Logic tương tự: cộng/trừ 0.5 tùy theo dấu.

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

Cách tiếp cận Time Space Tên
1 O(1) O(1) Phương pháp cộng/trừ 0.5 và ép kiểu
2 O(1) O(1) Phương pháp kiểm tra phần thập phân
3 O(1) O(1) Phương pháp ép kiểu trực tiếp (Cẩn thận)

Bài học kinh nghiệm

  • Sử dụng việc cộng hoặc trừ 0.5 để di chuyển số đến ngay ranh giới tiếp theo trước khi cắt bỏ phần thập phân là kỹ thuật chuẩn để làm tròn số.
  • Ép kiểu từ double sang int ở hầu hết các ngôn ngữ C/C++ sẽ cắt bỏ phần thập phân (tròn về 0), điều này khác với làm tròn đến số nguyên gần nhất đối với số âm.

Lỗi thường gặp

  • Quên xử lý trường hợp số âm riêng biệt, dẫn đến in ra kết quả sai (ví dụ -100.5 tròn thành -100 thay vì -101).
  • Sử dụng hàm round() có sẵn bị cấm theo đề bài.

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.