Hướng dẫn giải của Làm Tròn Điểm
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ậpTác giả: , , ,
Hiểu bài toán
Bài toán yêu cầu làm tròn điểm số của sinh viên dựa trên các quy tắc:
- Nếu điểm < 38: giữ nguyên.
- Nếu điểm >= 38:
- Nếu phần dư khi chia cho 5 nhỏ hơn 3 (tức là 0, 1, 2): giữ nguyên.
- Nếu phần dư khi chia cho 5 lớn hơn hoặc bằng 3 (tức là 3, 4): làm tròn lên số chia hết cho 5 tiếp theo.
Điểm đặc biệt là nếu làm tròn lên tạo ra số chia hết cho 5, đó cũng là điểm số mới. Ví dụ, 38 sẽ được làm tròn lên 40 vì 38 % 5 = 3, và 5 - 3 = 2 < 3? Không, quy tắc là 'nếu phần dư >= 3 thì làm tròn lên'. 38 % 5 = 3, nên làm tròn lên 40. Tương tự 47 % 5 = 2 (< 3) nên giữ nguyên 47.
Các cách tiếp cận
Cách Logic Phép chia lấy dư (Modulo Logic)
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
while (n--) {
int score;
cin >> score;
if (score >= 38 && score % 5 >= 3) {
score += (5 - score % 5);
}
cout << score << "\n";
}
return 0;
}
- Time Complexity: O(n)
- Space Complexity: O(1)
Đây là cách tiếp cận trực tiếp nhất. Với mỗi điểm số, ta kiểm tra hai điều kiện:
score >= 38: Điểm phải từ 38 trở lên mới được xem xét làm tròn.score % 5 >= 3: Phần dư khi chia cho 5 phải là 3 hoặc 4. Nếu cả hai điều kiện đều đúng, ta cộng vào số cần thiết để tròn lên 5. Ví dụ: 38 % 5 = 3, ta cộng 2 (5 - 3) để được 40. Code này xử lý ngắn gọn và hiệu quả ngay trong vòng lặp.
Cách Approach 2: Vòng lặp tăng dần (Increment Loop)
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int a;
cin >> a;
if (a < 38) {
cout << a << '\n';
} else {
int t1 = a % 5;
if (t1 >= 3) {
while (a % 5 != 0) a++; // Tăng a đến khi chia hết cho 5
cout << a << '\n';
} else {
cout << a << '\n';
}
}
}
}
- Time Complexity: O(n)
- Space Complexity: O(1)
Cách tiếp cận này sử dụng vòng lặp while để tăng điểm số lên từng đơn vị cho đến khi nó chia hết cho 5. Logic là:
- Nếu điểm < 38: In ra.
- Nếu điểm >= 38:
- Tính phần dư
t1 = a % 5. - Nếu
t1 >= 3: Bắt đầu vòng lặpwhile (a % 5 != 0) a++. Vì điều kiệnt1 >= 3đảm bảo rằng chỉ mất tối đa 2 bước tăng (ví dụ 38 -> 39 -> 40) để đến số chia hết cho 5. Vòng lặp này sẽ dừng lại ở số chia hết cho 5 đó. - Nếu
t1 < 3: In ra số gốc. Phương pháp này đúng nhưng cồng kềnh hơn so với tính toán trực tiếp.
- Tính phần dư
Cách Approach 3: Kiểm tra điều kiện trực tiếp
#include <iostream>
using namespace std;
int main() {
int n; cin >> n;
while(n--) {
int d; cin >> d;
if (d < 38) {
cout << d;
} else {
int r = d % 5;
// Điều kiện 5 - r < 3 có nghĩa là r > 2 (tức r >= 3)
// 5 - r là số cần cộng thêm
if (5 - r < 3) cout << (d + (5 - r));
else cout << d;
}
if (n) cout << "\n";
}
return 0;
}
- Time Complexity: O(n)
- Space Complexity: O(1)
Đây là biến thể của Approach 1, sử dụng một công thức toán học khác để kiểm tra.
Thay vì kiểm tra d % 5 >= 3, code này kiểm tra 5 - r < 3.
Giải thích:
r = d % 5(giá trị 0, 1, 2, 3, 4).5 - rlà số tiền cần cộng để tròn lên.- Nếu
r = 0: 5 - 0 = 5 (>= 3) -> False -> Giữ nguyên. Đúng. - Nếu
r = 2: 5 - 2 = 3 (>= 3) -> False -> Giữ nguyên. Đúng. - Nếu
r = 3: 5 - 3 = 2 (< 3) -> True -> Cộng thêm 2. Đúng. - Nếu
r = 4: 5 - 4 = 1 (< 3) -> True -> Cộng thêm 1. Đúng. Logic này hoàn toàn chính xác và là một cách diễn đạt khác của quy tắc làm tròn.
Phân tích độ phức tạp
| Cách tiếp cận | Time | Space | Tên |
|---|---|---|---|
| 1 | O(n) | O(1) | Logic Phép chia lấy dư (Modulo Logic) |
| 2 | O(n) | O(1) | Approach 2: Vòng lặp tăng dần (Increment Loop) |
| 3 | O(n) | O(1) | Approach 3: Kiểm tra điều kiện trực tiếp |
Bài học kinh nghiệm
- Vấn đề chỉ yêu cầu xử lý các số nguyên, phép toán % và phép cộng cơ bản là đủ.
- Điều kiện quan trọng nhất là
score >= 38vàscore % 5 >= 3. Kết hợp hai điều kiện này là chìa khóa.
Lỗi thường gặp
- Làm tròn sai các số nhỏ hơn 38 (ví dụ: 33, 34) nếu bỏ qua điều kiện
>= 38. - Tính toán sai giá trị cộng thêm (ví dụ: cộng thẳng phần dư thay vì trừ cho 5).
Bình luận