OpenJudge NOI 1.13 08:特殊日历计算

【题目链接】

OpenJudge NOI 1.13 08:特殊日历计算

【题目考点】

1… 取模运算

【解题思路】

我们用的是现实日历,题目中设定的是特殊日历,两种历法的一天是一样长的。也就是说两种历法的秒的长度是不一样的
先输入现实日历的日期。

1. 求时分秒

求出从当天0时0分0秒到当前时间h时m分s秒的总秒数ts,为ts=h*3600+m*60+s
现实日历中一天为 24 ∗ 60 ∗ 60 = 86400 24*60*60=86400 246060=86400秒,特殊日历中一天为 10 ∗ 100 ∗ 100 = 100000 10*100*100=100000 10100100=100000秒。
将现实日历的秒数转为特殊日历中的秒数,需要做 t s / 86400 ∗ 100000 = t s ∗ 125 / 108 ts/86400*100000=ts*125/108 ts/86400100000=ts125/108,即ts = ts*125/108
而后在特殊日历中:
ts%100为秒数,ts/100%100为分钟数,ts/10000为小时数。

2. 求日月年

把2000年1月1日当做第0天,求出该日期是第几天。
设一个函数getDayNum获取y年m月d日是从2000年1月1日起的第几天。

  • i从2000遍历到y-1,根据第i年是否是闰年统计每年的天数,加和。
  • i从1遍历到m-1,统计第i月的天数,加和。
  • 最后天数加上d-1(由于日期从1开始)

用getDayNum函数求出总天数td,而后将该天数转为特殊日历中的日、月、年。
特殊日历中10天一周,10周一个月,也就是100天一个月。10个月1年。由于日、月从1开始,所以求出的数值要加1。
td%100+1即为日,td/100%10+1即为月,td/1000为年。

【题解代码】

解法1:
#include<bits/stdc++.h>
using namespace std;
bool isLeap(int y)//y是否是闰年 
{
    return y%400 == 0 || y%100 != 0 && y%4 == 0;
}
int getDayNum(int y, int m, int d)
{
    int day = 0;//从2000.1.1到y年m月d日的总天数
    for(int i = 2000; i < y; ++i)
    {
        if(isLeap(i))
            day += 366;
        else
            day += 365;
    }
    for(int i = 1; i < m; ++i)
    {
        if(i == 2)  
            day += isLeap(y) ? 29 : 28;
        else if(i == 4 || i == 6 || i == 9 || i == 11)
            day += 30;
        else
            day += 31;
    }
    day += d-1;
    return day;
}     
int main()
{
    int n, k, h, mi, s, d, mo, y, td, ts;
    scanf("%d", &n);
    while(n--)
    {
        scanf("%d:%d:%d %d.%d.%d", &h, &mi, &s, &d, &mo, &y);//h:时 mi:分 s:秒 d:日 mo:月 y:年 
        ts = h*3600+mi*60+s;//从0:0:0到h:mi:s的总秒数 
        ts = ts*125/108;//将现实日历中的秒数转为特殊日历中的秒数。 
        s = ts%100, ts /= 100;//特殊日历下的秒、分、时 
        mi = ts%100, ts /= 100;
        h = ts;
        td = getDayNum(y, mo, d);//从1.1.2000到d.mo.y的总天数 
        d = td%100+1, td /= 100;//特殊日历下的日、月、年 
        mo = td%10+1, td /= 10;//日、月从1开始,所以要加1 
        y = td;
        printf("%d:%d:%d %d.%d.%d\n", h, mi, s, d, mo, y);//注意:月日从1开始
    }
    return 0;
}
解法2:
#include<bits/stdc++.h>
using namespace std;
bool isLeap(int y)//y是否是闰年 
{
    return y%400 == 0 || y%100 != 0 && y%4 == 0;
}
int getDayNum(int y, int m, int d)
{
    int day = 0;//从2000.1.1到y年m月d日的总天数
    for(int i = 2000; i < y; ++i)
    {
        if(isLeap(i))
            day += 366;
        else
            day += 365;
    }
    for(int i = 1; i < m; ++i)
    {
        if(i == 2)  
            day += isLeap(y) ? 29 : 28;
        else if(i == 4 || i == 6 || i == 9 || i == 11)
            day += 30;
        else
            day += 31;
    }
    day += d-1;
    return day;
}     
int main()
{
    int n, k, h, mi, s, d, mo, y, td, ts;
    scanf("%d", &n);
    while(n--)
    {
        scanf("%d:%d:%d %d.%d.%d", &h, &mi, &s, &d, &mo, &y);//h:时 mi:分 s:秒 d:日 mo:月 y:年 
        ts = h*3600+mi*60+s;//从0:0:0到h:mi:s的总秒数 
        ts = ts*125/108;//将现实日历中的秒数转为特殊日历中的秒数。 
        s = ts%100;//特殊日历下的秒、分、时 
        mi = ts/100%100;
        h = ts/10000;
        td = getDayNum(y, mo, d);//从1.1.2000到d.mo.y的总天数 
        d = td%100+1;//特殊日历下的日、月、年 
        mo = td/100%10+1;//日、月从1开始,所以要加1 
        y = td/1000;
        printf("%d:%d:%d %d.%d.%d\n", h, mi, s, d, mo, y);//注意:月日从1开始
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值