OpenJudge NOI 1.13 32:日历问题

【题目链接】

OpenJudge NOI 1.13 32:日历问题

【题目考点】

1. 字符串
2. 计数

【解题思路】

看测试数据可以知道2000-1-2是星期日,所以2000-1-1是星期六。
用0,1,2,…,6来表示星期日,星期一,…,星期六。

解法1:分别推算年、月、日

输入经过的总天数为td
从星期六经过1天后为星期日,即(6+1)%7。经过2天后为星期1,即(6+2)%7,经过td天后的星期为(6+td)%7
先从2000年开始,求出当年天数,如果td大于等于当年天数,就经过这一年,td减少这一年的天数。不断循环,直到td小于当年的天数。年份就确定了。
而后从1月开始,只要td大于等于当月天数,就减去当月天数,而后看下一个月。不能再减时,就确定了月份。
最后就是当月1日开始要经过td天,1+td即为最后的日期。
最后输出年月日和星期。

解法2:设日期类,推下一天

设日期类,包含属性:年、月、日、星期。
设方法getMonthDay,获取本月的天数。
设方法:变为下一天的日期。先让日增加1,如果超出了当月的天数,则月份数加1,日变为1。如果月份数大于12,则年加1,月变为1。
声明日期对象,起始日期为2000-1-1星期六。输入总天数td,循环td次,每次让日期变为下一天的日期。最后输出这个日期。

【题解代码】

解法1:分别推算年、月、日
#include <bits/stdc++.h>
using namespace std;
int md[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char ds[7][15] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
bool isLeap(int y)
{
    return y%400 == 0 || y%100 != 0 && y%4 == 0;
}
int getYearDay(int y)//获取y年有多少天 
{
    return isLeap(y) ? 366 : 365;
}
int main()
{
    int td, y = 2000, m = 1, d = 1, day = 6;//day:星期,0为星期日,1为星期1,6为星期6 
    scanf("%d", &td);
    day = (day+td)%7;
    while(td >= getYearDay(y))
    {
        td -= getYearDay(y);
        ++y; 
    }
    md[2] = isLeap(y) ? 29 : 28;
    while(td >= md[m])
    {
        td -= md[m];
        m++;
    }
    d += td;
    printf("%d-%02d-%02d %s", y, m, d, ds[day]); 
    return 0;
}
解法2:日期类 取下一天
#include <bits/stdc++.h>
using namespace std;
string ds[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
struct Date
{
    int y, m, d, x;//y年 m月 d日 x星期 0为星期日,1为星期1,6为星期6 
    Date(int a, int b, int c, int e):y(a), m(b), d(c), x(e){}
    bool isLeap()
    {
        return y%400 == 0 || y%100 != 0 && y%4 == 0;
    }
    int getMonthDay()
    {
        if(m == 2)
            return isLeap() ? 29 : 28;
        else if(m == 4 || m == 6 || m == 9 || m == 11)
            return 30;
        else
            return 31;
    }
    void nextDay()//日期变为下一天 
    {
        x = (x+1)%7;//星期变为下一个 
        d++;
        if(d > getMonthDay())
        {
            d = 1;
            m++;
            if(m > 12)
            {
                m = 1;
                y++;
            }
        }
    }
    void show()
    {
        cout << y << '-' << setw(2) << setfill('0') << m << '-' << setw(2) << setfill('0') << d << ' ' << ds[x] << endl;
    }
};
int main()
{
    int td;
    cin >> td;
    Date date(2000, 1, 1, 6);//2000-1-1 星期6 
    for(int i = 1; i <= td; ++i)
        date.nextDay();
    date.show();
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值