打鱼晒网问题, 初见日期计算

刚刚开始学习,在题库里面抽到这一题。

某人三天打渔两天晒网,假设他从1990年1月1日开始打渔三天,然后晒网两天,请编程回答任意的一天他在打渔还是晒网。
一个男孩工作3天,而请假2天。如果他在1990年1月1日工作,那么对于通过键盘输入的日期,请编写一个程序来确定男孩在做什么,工作或休息?
输入和输出示例:
1)输入
1990-01-05
输出:
他正在休息。
2)输入:
1990-01-07
输出:
他正在工作。
3)输入:
1990-01-33
输出:
输入无效。
输入数据格式:“%4d-%2d-%2d”
输出数据格式:“输入无效。”或“他正在休息。” 或“他正在工作。”

  1. 闰年的判别表达式: 四位年份,闰年满足以下条件,~~ 后两位被 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;
}
posted @ 2019-11-20 14:32  哒啉  阅读(462)  评论(0编辑  收藏  举报