题目标题: 高斯日记
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
请严格按照格式,通过浏览器提交答案。
注意:只提交这个日期,不要写其它附加内容,比如:说明性的文字。
分析:
网上的快速解法:
先看1778是闰年么?答案是不是,所以 8113 - 365= 7748,
又1779也不是,所以再减365得7383,然后1780是的,所以减去366得7017,
又1781,1782,1783,肯定都不是所以连减3个365得5922,
然后又是闰年,-366,再-365 - 365-365 -366-365-365 -365 -366 -365-365 -365~-366 -365-365 -365 1799 得
78,即这一天是1799年4月30日之后的78天,5月31天,-31,6月30天,-30,剩17天,
此时即加上两个月,为1799年6月30日,然后往后数17天,即为1799年7月16日。 //注意这里,6月30日,往后数17天得到的是7月16日,奇怪吧?
所以说他是从6月30日开始数起的,高斯出生的那天过去了,也算是一天。
答案即为:1799-07-16
我的解法:
题意为:给一个日期,一个天数,求过完这个天数后的日期。
我们可以模拟现实,天数大了一年一年过,小了一月一月过。
1.判断所给日期的那个月份能否过完
2.判断能过几年,此时要注意闰年
1‘今年是闰年,且今年的2月没 过,则过了今年天数要减去366
2’今年的2月已经过了,且明年是闰年,则过了今年天数要减去366
3.最后剩余的天数再判断能过几个月
此代码输入年、月、日、经过的天数(需大于0),将输出结果日期
如果发现哪里有纰漏,请不吝赐教!
#include <cstdio>
#include <iostream>
using namespace std;
int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int y, m, d, sum;
//判断年数 n 是否为闰年
bool isLeapYear(int n)
{
return n % 4 == 0 && n % 100 != 0 || n % 400 == 0;
}
//计算结果日期
void display()
{
if (isLeapYear(y)) //判断这一年是否为闰年
month[2] = 29;
int restOfDay = month[m] - d; //判断天数能否过完这个月
if(sum > restOfDay) //能过完这个月,则将这个月过完
{
sum -= restOfDay;
m++;
}
else { //不能过完这个月,将天数加上即可
d += sum;
return;
}
//再判断能过几年
while(sum > 365)
{
if (isLeapYear(y) && m < 2 || isLeapYear(y + 1) && m > 1)
sum -= 366;
else
sum -= 365;
y++;
}
//剩下不满一年的时间再过完
for(int i = m + 1; ; i++)
{
if (i > 12) { //这一年过完了
i = 1;
y++;
}
if (i == 2) //二月份要特殊判断
{
if (isLeapYear[y])
month[2] = 29;
else
month[2] = 28;
}
if (sum >= month[i]) //这个月能过完
{
sum -= month[i];
m++;
}
else
break;
}
d = sum; //最终的日就是剩下的天数
}
int main()
{
while (~scanf("%d%d%d%d", &y, &m, &d, &sum))
{
sum--; //题中给的数据将高斯出生的那天算一天了,这里天数减一
display();
cout << y << "/" << m << "/" << d << endl;
}
return 0;
}