法1:
我的想法及其简单
根据当前的年月日,求出本年度度过了多长时间
随后加到跳过天数上
所得到的跳过天数,就是从一年的起始处开始算起的
再求出,这是第几年,减去中间各年度过的时间
即得到了对应年,已经对应年度过的时间
随后根据对应年和对应年度过时间,求出其日期
#include <bits/stdc++.h>
using namespace std;
static int BeforeThisMonth[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
void NewMandD(const int &Y,int &M,int &D,int &RestDays)
{//用于确定,在当前的年和跳过的天数下,月和日是多少
int isRunNian = 0;
if ((!(Y % 4) && Y % 100) || !(Y % 400))
isRunNian = 1;
if (isRunNian && RestDays > 60)
RestDays--;
for(int i=0;;i++)
{
if(RestDays<=BeforeThisMonth[i])
{
M=i;
break;
}
}
D = RestDays - BeforeThisMonth[M - 1];
}
int WhichYear(int Y,int &NewDays,int &RestDays)
{//用于确定,现在是第几年
int tempY=Y;
for(int i=Y;;Y++)
{
if(!(Y%4)&&Y%100||!(Y%400))
{
if(NewDays>366)
NewDays-=366;
else
{
RestDays=NewDays;
return Y;
}
}
else
{
if(NewDays>365)
NewDays-=365;
else
{
RestDays=NewDays;
return Y;
}
}
}
}
int PastDaysThisY(const int &Y,const int &M,const int &D)
{//用于确定,在当前的年月日下,一年过去了几天
int isRunNian=0;
if(!(Y%4)&&Y%100||!(Y%400))
isRunNian=1;
if (M >= 3 && isRunNian == 1)
return BeforeThisMonth[M - 1] + D + 1;
else
return BeforeThisMonth[M - 1] + D;
}
void Leapdays(int &Y,int &M,int &D,const int &Leap)
{//用于确定跳过了Leap天后最终的年月日
int Past=PastDaysThisY(Y,M,D);
int NewDays=Leap+Past;
int RestDays=0;
Y=WhichYear(Y,NewDays,RestDays);
NewMandD(Y,M,D,RestDays);
}
void PrintDate(const int &Y,const int &M,const int &D)
{
printf("%04d-%02d-%02d\n",Y,M,D);
// cout << Y << '-';
// if (M >= 10)
// cout << M;
// else
// cout << '0' << M;
// if (D >= 10)
// cout << '-' << D << endl;
// else
// cout << "-0" << D << endl;
}
int main()
{
int Times=0;
int Y,M,D,Leap;
cin>>Times;
for(int z=0;z<Times;z++)
{
cin>>Y>>M>>D>>Leap;
Leapdays(Y,M,D,Leap);
// PrintDate(Y,M,D);
printf("%04d-%02d-%02d\n",Y,M,D);
}
return 0;
}
法2:
本方法就是将平闰年的各月的天数矩阵列出
随后也将平闰年的天数放入矩阵中
有两种关键操作
其一是将对应的日期转换为当前年经过多少天:
该操作是遍历对应的平闰年的对应行矩阵
将本月之前的各月份的矩阵加起来,并且加上当前的几号,就是当年过去的天数
其二是将当年过了多少天,转换为对应的日期
该操作是从1月开始遍历
在遍历的过程中有一个判断,若leap第一次小于等于当前的月份值,则得到几月,多余的天数则是几号,则跳出
若leap大于当前月份值,则将其减去对应月的天数,继续循环
#include <stdio.h>
#include <string.h>
//此处是平年和闰年的各月份的矩阵
int Month[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
//此处是平年和闰年的一年的总时间
int Year[2] = {365, 366};
int main()
{
int year, month, day, leap, repeat;
scanf("%d", &repeat);
while (repeat--)
{ //到此处,得到了循环总数
scanf("%d%d%d%d", &year, &month, &day, &leap);
//到此处得到了年月日,以及即将跳过的时间
int y;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
y = 1;
else
y = 0;
//以上即确定了当前年度的平闰年
for (int i = 0; i < month; i++)
{
leap += Month[y][i];
}
leap += day;
//以上即将本年度已经经过的时间全部加上了
//得到的新的leap是从本年的开始向后跳的
for (int i = year;; i++)
{ //此处for循环,可以求得最终的年数
if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0))
y = 1;
else
y = 0;
//以上即确定了当前年度i的平闰年
if (leap > Year[y])
leap -= Year[y];
//若不是最终年,则继续循环
else
{//在最终年的话,则跳出循环
month = 1;
while (leap > Month[y][month])
{//求出当前年的月份
leap -= Month[y][month];
month++;
}
day = leap;
year = i;
break;
}
}
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}