Bailian2964 日历问题【日期+模拟】

2964:日历问题
描述
在我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它们不是闰年。例如:1700, 1800, 1900 和 2100 不是闰年,而 1600, 2000 和 2400是闰年。 给定从公元2000年1月1日开始逝去的天数,你的任务是给出这一天是哪年哪月哪日星期几。
输入
输入包含若干行,每行包含一个正整数,表示从2000年1月1日开始逝去的天数。输入最后一行是−1, 不必处理。可以假设结果的年份不会超过9999。
输出
对每个测试样例,输出一行,该行包含对应的日期和星期几。格式为“YYYY-MM-DD DayOfWeek”, 其中 “DayOfWeek” 必须是下面中的一个: “Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday” 或 "Saturday“。
样例输入
1730
1740
1750
1751
-1
样例输出
2004-09-26 Sunday
2004-10-06 Wednesday
2004-10-16 Saturday
2004-10-17 Sunday
提示
2000.1.1. 是星期六
来源
2080

问题链接Bailian2964 日历问题
问题描述:(略)
问题分析
  这个问题是根据输入的天数(从2000年1月1日起),计算日期和星期。
  日期计算问题,用模拟法实现比较简单,先一年一年过,然后一个月一个月过,最后年月日就算出来了。
程序说明:本题与参考链接是同一题,使用参考链接的程序提交也AC。
参考链接POJ2080 ZOJ2420 Calendar【日期+模拟】
题记:(略)

AC的C语言程序如下:

/* Bailian2964 日历问题 */

#include <stdio.h>

char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int mdays[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


int leapyear(int year)
{
    return ( ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) ) ? 1 : 0;
}

int main(void)
{
    int n;
    while(~scanf("%d", &n) && n != -1) {
        int year = 2000;
        int month = 1;
        int week = (n + 6) % 7;

        /* 一年一年过 */
        for(;;) {
            int ydays = 365 + leapyear(year);
            if(n >= ydays)
                n -= ydays, year++;
            else
                break;
        }

        /* 一个月一个月过 */
        for(;;) {
            int day2 = (month == 2 ? mdays[month] + leapyear(year) : mdays[month]);
            if(n >= day2)
                n -= day2, month++;
            else
                break;
        }

        printf("%d-%02d-%02d %s\n", year, month, n + 1, days[week]);
    }

    return 0;
}

AC的C++语言程序如下:

/* POJ2080 ZOJ2420 Calendar */

#include <iostream>
#include <stdio.h>

using namespace std;

const char *DAYS[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const int MDAYS[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int leapyear(int year)
{
    return ( ((year%4==0) && (year%100!=0)) || (year%400==0) ) ? 1 : 0;
}

int monthdays(int year, int month)
{
    return month == 2 ? MDAYS[month] + leapyear(year) : MDAYS[month];
}

int main()
{
    int days, year, month, day, y, m;

    while(~scanf("%d", &days) && days != -1) {
        day = days;

        // 计算年:一年一年算
        for(year = 2000; ; year++) {
            y = 365 + leapyear(year);
            if(day < y)
                break;
            day -= y;
        }

        // 计算月:一个月一个月算
        for(month=1; ;month++) {
            m = monthdays(year, month);
            if(day < m)
                break;
            day -= m;
        }

        printf("%d-%02d-%02d %s\n", year, month, day + 1, DAYS[(6 + days) % 7]);
    }

    return 0;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值