2013 年蓝桥杯 C 语言 B 组省赛第 1 题 高斯日记
题目
题目标题: 高斯日记
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
请严格按照格式,通过浏览器提交答案。
注意:只提交这个日期,不要写其它附加内容,比如:说明性的文字。
题目分析
这一题是一个结果填空题,可以使用 Excel 解出答案。需要注意的有一下几点:
- 充分利用和验证题目的示例,确定高斯出生的那一天是按第一天而不是第 0 天计算的。
- 注意答案的提交格式,不要写成“1980-3-21”,而是:“1980-03-21”。
- 注意闰年和非闰年的区别。能被 4 整除, 但不能被 100 整除的是闰年, 或者能被 400 整除的也是闰年. 闰年有 366 天,非闰年有 365 天. 闰年的 2 月有 29 天, 非闰年的 2 月有 28 天. 每 4 年中会有一个闰年.
首先, 借助 Excel 来计算出答案.
写下高斯的生日, 右键将单元格格式设置成"日期":
图 1
根据年份和月份的规律可以计算出这样一个表格:
图 2
根据如下图所示的验证结果可以看到, 高斯出生的那天是按照第一天计算的, 同时这也验证了我们的计算方式是正确的:
图 3
当我们选中到 1978 年的时候,求和结果显示有 7916 天:
图 4
8113 - 7916 = 197
之后的 1799 年是非闰年, 其 2 月有28天, 计算如下:
31(1月) + 28(2月) + 31(3月) + 30(4月) + 31(5月) + 30(6月) = 181
197 - 181 = 16
因此可以知道, 高斯获取博士学位那一年是 1799 年 07 月 16 日
填写的答案就是:
1799-07-16
另外, 本题也可以使用编程解决, 程序如下:
//模仿翻日历的方式计算高斯获得博士学位的日期
#include<iostream>
using namespace std;
//判断是否是闰年的布尔函数
bool isLeapYear(int y){
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}
int main(int argc, const char *argv[]){
int y = 1777;
int m = 4;
int d = 30;
for (int i = 0; i < 8112; i++){
d++;
//如果出现 12 月 32 日 则代表下一年
if (m == 12 && d == 32){
y++;
m = 1;
d = 1;
continue;
}
//对除了 12 月之外的其他有 31 天的月份进行判断
if ((m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10) && d == 32){
m++;
d = 1;
continue;
}
//对除了 12 月之外的其他有 30 天的月份进行判断
if ((m == 4 || m == 6 || m == 9 || m == 11) && d == 31){
m++;
d = 1;
continue;
}
//判断闰年的 2 月
if (m==2 && isLeapYear(y) && d == 30){
//闰年的二月有 29 天, 因此如果出现第 30 天就需要进入下一月.
m ++;
d = 1;
continue;
}
//判断非闰年的 2 月
if (m == 2 && !isLeapYear(y) && d == 29){
//非闰年的二月有 28 天, 因此如果出现第 29 天就需要进入下一月.
m++;
d = 1;
continue;
}
}
cout << y << " " << m << " " << d << endl;
return 0;
}
运行结果:
图 5
需要注意的是, 填写答案时要按照要求的格式填写:
1799-07-16