百练OJ 2967 特殊日历计算

题目描述

有一种特殊的日历法,它的一天和我们现在用的日历法的一天是一样长的。它每天有10个小时,每个小时有100分钟,每分钟有100秒。10天算一周,10周算一个月,10个月算一年。现在要你编写一个程序,将我们常用的日历法的日期转换成这种特殊的日历表示法。这种日历法的时、分、秒是从0开始计数的。日、月从1开始计数,年从0开始计数。秒数为整数。假设 0:0:0 1.1.2000 等同于特殊日历法的 0:0:0 1.1.0。
题目来源:百练2967

输入描述

输入:第一行是一个正整数 N ,表明下面有 N 组输入。每组输入有一行,格式如下:hour:minute:second day.month.year
表示常规的日期。日期总是合法的。2000 <= year <= 50000。

7
0:0:0 1.1.2000
10:10:10 1.3.2001
0:12:13 1.3.2400
23:59:59 31.12.2001
0:0:1 20.7.7478
0:20:20 21.7.7478
15:54:44 2.10.20749

输出:每组输入要求输出一行。格式如下:mhour:mmin:msec mday.mmonth.myear 是输入日期的特殊日历表示方法。

0:0:0 1.1.0
4:23:72 26.5.0
0:8:48 58.2.146
9:99:98 31.8.0
0:0:1 100.10.2000
0:14:12 1.1.2001
6:63:0 7.3.6848

输出描述

思路

本题不难,主要是要考虑平年闰年以及day、month、year从0计数还是1计数的问题

具体实现

#include <cstdio>
int main(){
    int n;
    scanf("%d", &n);
    int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //平年
    int b[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //闰年
    while(n--){
        int hour, minute, second, day, month, year;
        scanf("%d:%d:%d %d.%d.%d", &hour, &minute, &second, &day, &month, &year);
        if(year > 2000) {
            day += (year - 2000) * 365 + (year - 2001) / 4 - (year - 2001) / 100 + (year - 2001) / 400 + 1;
        }  //加上被4整除的年份,减去被100整除的年份再加上被400整除的年份,即所有闰年的年份
        if(year%4 != 0 || (year%100 == 0 && year %400 != 0)){
            for(int i = 1; i < month; i++) day += a[i];
        } //对输入的当年来说是平年则用a数组
        else{
            for(int i = 1; i < month; i++) day+= b[i];
        } //对输入的当年来说是闰年则用b数组
        year = day/1000; 
        if(day%1000 == 0){
            year--; month = 10;
        }  //这里的day算上了第一天1.1 2000所以如果day是1000 2000 这样的数则year需要-1(year从0开始算),month为10
        else if(day%100 == 0) month = (day%1000)/100;  //month从1开始算故1100属于1月
        else month = (day%1000)/100 + 1;  //month从1开始算所以1122属于2月而非1月
        day = (day-1)%100 + 1;  //day从1开始算,则1100属于100天
        second += hour*3600 + minute*60;
        second = second*125/108;  
        hour = second/10000;
        minute = (second%10000)/100;
        second = second%100;
        printf("%d:%d:%d %d.%d.%d\n", hour, minute, second, day, month, year);
    }
    return 0;
}

时间复杂度

小结

注意day、year、month、second等从0开始算还是1开始算,涉及到诸如1000day属于0year还是1year等诸多问题
如果0~999day属于 0year,0 ~99day属于0month,则 year = day/1000,month = (day%1000)/100;
如果1~1000day属于0year,1~100day属于1month,则year= (day-1)/1000,month = ((day%1000) - 1)/100 + 1;
注意闰年是整除4的年份,且整除100不能被400整除的是平年。
可以单独设函数int judge(int year){
if (year%4 != 0 || (year%100 == 0 && year %400 != 0)) return 0; else return 1;}来逐一判断
也可以利用概率论知识,先加上所有能被4整除的年份再减去所有能被100整除的再加上所有能被400整除的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值