大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
解题思路:
这个题目存在边界问题的界定,就是出生的那天算是第零天还是第一天,这道题目经过核算出生的那天算是第零天。
最开始写的这个代码就是为了验证出生的那天是第零天还是第一天。我写的代码出生的那天是第一天
- 一个判断闰年的函数
- 利用前缀和维护,判断给出的日期是该年的第几天
- 计算最开始的那年还剩几天,两年中间完整的年份的天数,最后的那一天前有多少天,这三个加起来就是两个日期之间相差的天数
本来我还想写一个函数直接输出最后的天数,但是发现其实写了这些代码直接往上带带出8112天(出生天是第一天)的日期就行了。
下面附上代码验算过程
#include <bits/stdc++.h>
using namespace std;
bool judge(int year) //判断闰年
{
if((year%4==0&&year%100!=0)||(year%4==0&&year%400==0)){
return true;
}
else return false;
}
int WhatDay(int year,int month,int day){ //计算给出的的日期是该年的第几天
int ans=0;
int CommonYear[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int LeapYear[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int sumcy[13]; //前缀和
int sumly[13]; //前缀和
for(int i=1;i<=12;i++)
{
sumcy[i]=CommonYear[i]+sumcy[i-1];
sumly[i]=LeapYear[i]+sumly[i-1];
}
if(judge(year)==true){
ans=sumly[month-1]+day;
}
else{
ans=sumcy[month-1]+day;
}
return ans;
}
int HowManyDays(int yearNow,int monthNow,int dayNow,int yearYet,int monthYet,int dayYet) //计算两个日期之间相差的天数
{
int ans=0;
for(int year=yearYet+1;year<=yearNow-1;year++) //计算两个日期之间完整的年天数
{
if(judge(year)==true)
{
ans+=366;
}
else{
ans+=365;
}
}
//计算过去的那一年还剩多少天
if(judge(yearYet)==true){
ans=ans+366-WhatDay( yearYet, monthYet, dayYet);
}
else{
ans=ans+365-WhatDay( yearYet, monthYet, dayYet);
}
//计算当前这一年是这一年的第多少天
ans+=WhatDay(yearNow,monthNow,dayNow);
return ans;
}
int main()
{
int year,month,day;
cout<<HowManyDays(1799,7,16,1777,4,30);
//system("pause");
return 0;
}