Hướng dẫn giải của Tìm số ngày của tháng
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 xác định số ngày trong một tháng của một năm dương lịch dựa trên đầu vào là tháng (month) và năm (year). Người dùng cần tuân thủ các điều kiện hợp lệ: 1 <= month <= 12 và year > 0. Nếu input không thỏa mãn, in ra 'INVALID'. Cần xử lý đúng năm nhuận để tính số ngày cho tháng 2.
Các cách tiếp cận
Cách Kiểm tra điều kiện và in ra theo từng trường hợp (Nested If-Else)
#include <stdio.h>
int main(){
int m,y;
scanf("%d %d",&m ,&y);
if(m<=0 || m>12 || y<=0) printf("INVALID");
else{
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12) printf("31");
else if(m==4||m==6||m==9||m==11) printf("30");
else{
if(y%400==0||(y%4==0 && y%100!=0)) printf("29");
else printf("28");
}
}
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Hàm main nhận input tháng và năm. Trước hết, kiểm tra xem tháng có nằm trong khoảng [1, 12] và năm có lớn hơn 0 không. Nếu không, in 'INVALID'. Nếu hợp lệ, sử dụng cấu trúc if-else lồng nhau để phân loại tháng: in 31 ngày cho các tháng 1, 3, 5, 7, 8, 10, 12; in 30 ngày cho các tháng 4, 6, 9, 11. Nếu không phải các tháng trên (tức là tháng 2), kiểm tra điều kiện năm nhuận (chia hết cho 400 hoặc (chia hết cho 4 và không chia hết cho 100)) để in 29 hoặc 28.
Cách Sử dụng hàm kiểm tra năm nhuận và cấu trúc rẽ nhánh
#include <stdio.h>
#include <stdbool.h>
int m;
long long y;
bool filter(int a, long long b){
if ((a < 1) || (a > 12)) return false;
if (b < 0) return false;
return true;
}
bool nam_nhuan(long long a){
if (a % 400 == 0) return true;
else if ((a % 4 ==0) && (a % 100 != 0)) return true;
else return false;
}
void process(){
if (m == 2){
if (nam_nhuan(y)) printf("%d", 29);
else printf("%d", 28);
}
else{
switch (m){
case 1: case 3: case 5: case 7: case 8: case 10: case 12: printf("%d", 31); break;
case 4: case 6: case 9: case 11: printf("%d", 30); break;
}
}
}
int main(){
scanf("%d%lld", &m, &y);
if (filter(m,y) == false) printf("INVALID");
else process();
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Cách tiếp cận này tách biệt logic kiểm tra tính hợp lệ và xử lý logic tính số ngày. Hàm filter đảm bảo input hợp lệ. Hàm nam_nhuan helper giúp code dễ đọc hơn. Trong hàm process, sử dụng switch statement để xử lý các tháng có 31 hoặc 30 ngày, và if để xử lý riêng tháng 2 dựa trên kết quả kiểm tra năm nhuận.
Cách Tối ưu hóa cấu trúc in ra (Cải tiến logic)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
if((a>0&&a<=12)&&(b>-10000&&b<=10000))
{
if((b%400==0)||(b%4==0&&b%100!=0))
{
if(a==2) printf("29");
}
else printf("28");
if(a==1||a==3||a==5||a==7||a==8||a==10||a==12) printf("31");
else {if(a!=2) printf("30");}}
else printf("INVALID");
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Đây là một biến thể của Approach 1 nhưng có cấu trúc hơi khác thường. Nó kiểm tra năm nhuận trước. Nếu là năm nhuận và là tháng 2, in 29. Nếu không, in 28. Sau đó, nó kiểm tra xem có phải là các tháng 31 ngày hay không. Nếu không phải là các tháng 31 ngày và cũng không phải là tháng 2 (đã được xử lý ở trên), nó in 30. Cách này tận dụng việc in giá trị 28 mặc định cho tháng 2 nếu không phải năm nhuận.
Phân tích độ phức tạp
| Cách tiếp cận | Time | Space | Tên |
|---|---|---|---|
| 1 | O(1) | O(1) | Kiểm tra điều kiện và in ra theo từng trường hợp (Nested If-Else) |
| 2 | O(1) | O(1) | Sử dụng hàm kiểm tra năm nhuận và cấu trúc rẽ nhánh |
| 3 | O(1) | O(1) | Tối ưu hóa cấu trúc in ra (Cải tiến logic) |
Bài học kinh nghiệm
- Cần kiểm tra tính hợp lệ của input (1 <= month <= 12, year > 0) trước khi tính toán.
- Quy tắc năm nhuận: Chia hết cho 400 HOẶC (chia hết cho 4 VÀ không chia hết cho 100).
- Các tháng 1, 3, 5, 7, 8, 10, 12 có 31 ngày.
- Các tháng 4, 6, 9, 11 có 30 ngày.
- Tháng 2 có 28 ngày, 29 ngày nếu là năm nhuận.
Lỗi thường gặp
- Quên kiểm tra điều kiện
year > 0(chỉ kiểm tramonth). - Sai điều kiện năm nhuận (ví dụ: chỉ kiểm tra
year % 4 == 0mà không loại trừ các năm chia hết cho 100 nhưng không chia hết cho 400). - Quên xử lý trường hợp
INVALIDkhi input nằm ngoài giới hạn cho phép. - Lỗi kiểu dữ liệu khi xử lý năm (ví dụ:
scanfkhông khớp với biếnlong longnếu dùng%d).
Bình luận