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
图 1

根据年份和月份的规律可以计算出这样一个表格:

图 2

根据如下图所示的验证结果可以看到, 高斯出生的那天是按照第一天计算的, 同时这也验证了我们的计算方式是正确的:

图 3

当我们选中到 1978 年的时候,求和结果显示有 7916 天:

图 4
图 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
图 5

需要注意的是, 填写答案时要按照要求的格式填写:
1799-07-16