打鱼晒网问题, 初见日期计算
刚刚开始学习,在题库里面抽到这一题。
某人三天打渔两天晒网,假设他从1990年1月1日开始打渔三天,然后晒网两天,请编程回答任意的一天他在打渔还是晒网。
一个男孩工作3天,而请假2天。如果他在1990年1月1日工作,那么对于通过键盘输入的日期,请编写一个程序来确定男孩在做什么,工作或休息?
输入和输出示例:
1)输入
1990-01-05
输出:
他正在休息。
2)输入:
1990-01-07
输出:
他正在工作。
3)输入:
1990-01-33
输出:
输入无效。
输入数据格式:“%4d-%2d-%2d”
输出数据格式:“输入无效。”或“他正在休息。” 或“他正在工作。”
- 闰年的判别表达式: 四位年份,闰年满足以下条件,~~ 后两位被 4整除 或者前两位被 4整除~~ 简单说,就是,被 400 整除的年 或 被 4 整除但 不被 100 整除的年
(year % 400) || (year % 100 != 0 && year % 400 != 0 )
#include <stdio.h>
int main(){
int m_days[13] ={0,31,28,31,30,31,30,31,31,30,31,30,31};
int year, month, day, sumdays = 0;
scanf("%4d-%2d-%2d", &year, &month, &day);
// 检测非法输入
if (year < 1990
|| month < 1
|| month > 12
|| day < 1
|| day > m_days[month])
{
printf("输入无效。\n");
return 0;
}
// 加上 每年的基本天数
sumdays += (year - 1990) * 365;
// 计算有多少个闰年 就额外加多少天
// 1992 年是闰年,每过四年是一个闰年
sumdays += ( (year - 1990) / 4 );
// 累加每月天数,其实,数组可以存成 {0 , 31, 59, 90 .....} 这样免去累加
for (int i = 1; i < month; i++){
sumdays += m_days[i];
}
// 加上这个月的天数
sumdays += day;
printf("%d\n", sumdays);
// 根据算法: 输入 1990-1-5 日,计算得 sumdays = 5
// 所以 1 2 3 4 5
// 在 sumdays - 1 整除 5 的余数 分别为 0 1 2 3 4
// 那么休息的条件就是 >= 3
// 如果 sumdays 不减一 整除 5 的余数 分别为 1 2 3 4 0
// 休息的条件是 > 3 || == 0
if ( ((sumdays - 1) % 5) >= 3){
printf("他正在休息。\n");
}else{
printf("他正在工作。\n");
}
return 0;
}