题目来源和说明

2009年上海交通大学计算机研究生机试真题,试图通过本次题解总结和梳理日期类问题的所有复试题目。代码模板参考王道考研机试!

题目描述

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天

样例

输入:
20110412
20110422
输出:
11

C++ 代码

#include<iostream>
#define ISYEAP(x) x%100 !=0 && x%4==0 || x%400==0 ? 1:0
//定义宏判断是否是闰年
using namespace std;
int dayOfMonth[13][2]={
    {0,0},
    {31,31},
    {28,29},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31}
}; //预存每月的天数,注意二月配合宏定义做特殊处理

struct Date{ //日期,方便日期的推移
    int Day;
    int Month;
    int Year;
    void nextDay() {
        Day++;
        if(Day>dayOfMonth[Month][ISYEAP(Year)]) {
            Day=1;
            Month++; //进入下一个月
            if(Month>12) { //月数超过12
                Month=1;
                Year++; //进入下一年
            }
        }
    }
};

int buf[5001][13][32]; //保存预处理的天数
int Abs(int x) { //求绝对值
    return x<0 ? -x:x;
}
int main() {
    Date temp;
    int cnt=0; //天数计数
    temp.Day=1;
    temp.Month=1;
    temp.Year=0;//初始化日期类对象为0年1月1日
    while(temp.Year!=5001) { //日期不超过5000年
        buf[temp.Year][temp.Month][temp.Day]=cnt; //该日与0年1月1日的天数差
        temp.nextDay(); //计算下一天日期
        cnt++; //计数器累加,每经过一天计数器+1
    }
    int d1,m1,y1;
    int d2,m2,y2;
    while(scanf("%4d%2d%2d",&y1,&m1,&d1)!=EOF) {
        scanf("%4d%2d%2d",&y2,&m2,&d2); //读入要计算的两个日期
        printf("%d\n",Abs(buf[y2][m2][d2]-buf[y1][m1][d1])+1);
    }
    return 0;
}

同类题目

  1. Day of Week https://www.nowcoder.com/questionTerminal/a3417270d1c0421587a60b93cdacbca0

C++代码

#include<iostream>
#include<string.h>
#define IYEAR(x) x%4==0 && x%100!=0 || x%400==0 ? 1:0
using namespace std;

int DayOfMonth[13][2]={
    {0,0},   
    {31,31}, 
    {28,29},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31}
};
struct Date {
    int year;
    int month;
    int day;
    void nextDay() {
        day++;
        if(day>DayOfMonth[month][IYEAR(year)]) {
            day=1;
            month++;
            if(month>12) {
                month=1;
                year++;
            }
        }
    }
};
int buf[5001][13][32];
char monthName[13][20]={
    "",
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
}; //月名,每个月名字对应下标1-12

char weekName[7][20]={
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"
}; //周名,每个周名对应下标0-6

int main() {
    Date temp;
    int cnt=0;
    temp.day=1;
    temp.month=1;
    temp.year=0;
    while(temp.year!=5001) { //假设最大年份数是5000
        buf[temp.year][temp.month][temp.day]=cnt;
        temp.nextDay();
        cnt++;
    }//以上与上一题一致,预处理出每一天与原点日期的天数差
    
    int d,m,y;
    char s[20];
    while(scanf("%d%s%d",&d,s,&y)!=EOF) {
        for(m=1;m<=12;m++) {
            if(strcmp(s,monthName[m])==0) break;
        }
         int days=buf[y][m][d]-buf[2022][3][31];//计算给定日期与今日日期的天数间隔
         days+=4;//2022、03、31是星期四,对应的数组小标应该是4
         puts(weekName[(days%7+7)%7]); //这样是为了处理days是负数的情况
    }
    return 0;
}


  1. 今年的第几天 https://www.nowcoder.com/questionTerminal/cc6ad889f95c49c08da1b338dd2e07ab
#include<iostream>
#define ISYEARP(X) X%4==0&&X%100!=0 || X%400==0 ? 1 : 0

using namespace std;

int DayOfMonth[13][2]={
    {0,0},   
    {31,31}, 
    {28,29},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31}
};
struct Date{
    int day;
    int month;
    int year;
    void nextday() {
        day++;
        if(day>DayOfMonth[month][ISYEARP(year)]) {
            day=1;
            month++;
            if(month>12) {
                month=1;
                year++;
            }
        }
    }
};
int buf[3001][13][32];

int main() {
    int cnt=0;
    Date temp;
    temp.year=0;
    temp.month=1;
    temp.day=1;
    while(temp.year!=3001) {
        buf[temp.year][temp.month][temp.day]=cnt;
        temp.nextday();
        cnt++;
    }
    int year,month,day;
    while(scanf("%d%d%d",&year,&month,&day)!=EOF) {
        int res=buf[year][month][day]-buf[year][1][1]+1;
        printf("%d\n",res);
    }
}

3.打印日期

#include<iostream>
using namespace std;

int dayOfMonth[13]={
    0,31,28,31,30,31,30,31,31,30,31,30,31
};
int main() {
    int y,n;
    while(scanf("%d%d",&y,&n)!=EOF){
        if(y%4==0&&y%100!=0 || y%400==0) {
            dayOfMonth[2]=29;
        }
        int i;
        for(i=1;i<=12;i++) {
            if(n<=dayOfMonth[i]) break;
            n-=dayOfMonth[i];
        }
        printf("%04d-%02d-%02d\n",y,i,n);
    }
    return 0;
}