洛谷 P2655 2038年问题

Posted 一蓑烟雨任生平

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P2655 2038年问题相关的知识,希望对你有一定的参考价值。

题目描述

网络时代,机会与危机共存。“千年虫”解决之后,会不会有新的“虫”出现?回答是肯定的,“2038年”就是一个新的关卡。

也许大家都已经知道计算机的2000年问题是什么概念,但是什么时候又冒出来一个2038年问题的呢?

用C语言编制的程序不会碰到2000年问题,但是会有2038年问题。这是因为,大多数C语言程序都使用到一个叫做“标准时间库”的程序库,这个时间库用一个标准的4字节也就是32位的形式来储存时间信息。

当初设计的时候,这个4字节的时间格式把1970年1月1日凌晨0时0分0秒作为时间起点,这时的时间值为0。以后所有的时间都是从这个时间开始一秒一秒累积得来的。

比方说如果时间已经累积到了919642718这个数值,就是说这时距离1970年1月1日凌晨0时0分0已经过去了919642718秒,换算一下就应该是1999年2月21日星期天16时18分38秒。

这样计算时间的好处在于,把任意两个时间值相减之后,就可以很迅速地得到这两个时间之间相差的秒数,然后你可以利用别的程序把它换算成明白易懂的年月日时分秒的形式。

一个4字节也就是32位的存储空间的最大值是2147483647,请注意!2038年问题的关键也就在这里———当时间一秒一秒地跳完2147483647那惊心动魄的最后一秒后,它就会转为负数也就是说时间无效。那一刻的准确的时间为2038年1月19日星期二晚上03:14:07,之后所有用到这种“标准时间库”的C语言程序都会碰到时间计算上的麻烦。

你要解决的问题是,现有一台计算机,表示时间的变量长度为N位。给定一个“时间起点”,求出对于这个“时间起点”时间,最后的有效时间是什么时候。

输入输出格式

输入格式:

 

第一行为数据组数T

第2……T+1行,每行7个数字描述一组数据,分别为表示时间的变量长度(二进制位数),然后是“时间起点”的年份,月份,日期,小时,分钟,秒数。

 

输出格式:

 

T行,对于每组数据,输出1行,6个数字,分别表示最后的有效时间的年份,月份,日期,小时,分钟,秒数。

 

输入输出样例

输入样例#1: 复制
1                             
16 2000 1 1 0 0 0
输出样例#1: 复制
2000 1 1 9 6 7
输入样例#2: 复制
2
32 1970 1 1 0 0 0
32 2015 11 8 8 30 0
输出样例#2: 复制
2038 1 19 3 14 7
2083 11 26 11 44 7

说明

对于50%的数据 变量的位数<=16;

对于所有数据,变量长度<=32,数据组数<=1000,0<=年份<=10000

思路:模拟。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int t,sum;
int tian,xh,fz,m;
int up,year,month,day,hour,mint,s;
void work1(int tian,int xh,int fz,int m){
    s+=m;if(s>=60){ s%=60;mint+=1; }
    mint+=fz;if(mint>=60){ mint%=60;hour+=1; }
    hour+=xh;if(hour>=24){ hour%=24;day+=1; }
    day+=tian;int flag=0;
    while(!flag){
        flag=0;
        if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
            if(day>31){ day-=31;month++; }
            else flag=1;
        }
        if(month==4||month==6||month==9||month==11){
            if(day>30){ day-=30;month++; }
            else flag=1;
        }
        if(month==2&&((year%100!=0&&year%4==0)||year%400==0)){
            if(day>29){ day-=29;month++;}
            else flag=1;
        }
        else if(month==2){
            if(day>28){ day-=28;month++; }
            else flag=1;
        }
        if(month>12){ year++;month=1;}
    }
}
int main(){
    //freopen("lpp.txt","r",stdin);
    //freopen("lpp.out","w",stdout);
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d%d%d%d",&up,&year,&month,&day,&hour,&mint,&s);
        long long tot=pow(2,up-1)-1;
        tian=tot/60/60/24;
        xh=(tot-tian*60*60*24)/60/60;
        fz=(tot-tian*60*60*24-xh*60*60)/60;
        m=tot-tian*60*60*24-xh*60*60-fz*60;
        work1(tian,xh,fz,m);
        printf("%d %d %d %d %d %d\n",year,month,day,hour,mint,s);
    }
}

 

以上是关于洛谷 P2655 2038年问题的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P2038 无线网络发射器选址 题解

洛谷 P2038 无线网络发射器选址

洛谷 P2038 无线网络发射器选址

Leetcode刷题Python LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色

AC日记——无线网络发射器选址 洛谷 P2038

2038 年嵌入式 Linux(32 位)解决方案? [复制]