蓝桥杯 高斯日记

66 篇文章 0 订阅
54 篇文章 0 订阅

网上给的都是结果,代码我来给吧。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

题目标题: 高斯日记

    大数学家高斯有个好习惯:无论如何都要记日记。


    他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210

    后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,

    它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

    高斯出生于:1777年4月30日。
    
    在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

    高斯获得博士学位的那天日记上标着:8113   

    请你算出高斯获得博士学位的年月日。

提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21

请严格按照格式,通过浏览器提交答案。
注意:只提交这个日期,不要写其它附加内容,比如:说明性的文字。

参考答案:1799-07-16

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

先看看别人的分析方法:

考场快速解题: 

先看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

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
先说一下,我的疑问:

         出生的那天过去了,算不算一天?如果算,就要减去出生的那一天,
如果不算,就不要减去那一天了。根据题目给的5343,是:1791年12月15日。
得出出生的那天过去了也算是一天的。看了别人的分析后,得出出生的那天过去后

也是算一天的。

出生的那天过去时那一刻是五月一日吗?我的代码得出的是五月0号,奇怪吧?

这一点我不很明白,望知道的盆友告知一二。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我的解题思路:

         其实本题可以简述为,从1777年4月30日开始算起,过了n天后,是XXXX年XX月XX日?

我的思路就是这么简单。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我解题的C++代码如下:

#include "stdafx.h"
#include<iostream>
using namespace std;

//判断年份是否是闰年
bool IsRunNian(int year)
{
	if(year%400==0||(year%4==0&&year%100!=0))
		return true;
	else
		return false;
}


//高斯出生于:1777年4月30日
//判断高斯出生n天之后,是XXXX年XX月XX日
void CalcYMD(int n)
{
	int arr[]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的天数,二月未考虑闰年

	int shengXia=31+30+31+31+30+31+30+31; //高斯出生后还剩下这么多天才过完1777年

	int year=1777,month=4,day=30; //高斯出生时的年、月、日

	if (n>shengXia) //算出年份
	{
		int i=1778;
		int tmp=n,count=1;
		tmp=IsRunNian(i++)?tmp-366:tmp-365;   //闰年有366天,平年有365天
		while (tmp>shengXia)
		{
			tmp=IsRunNian(i++)?tmp-366:tmp-365;
			count++;
		} 
		year=year+count;
	}

	if (n>0) //算出月份
	{
		int tmp=0,y=1777;
		for(int i=4;tmp<n;i++)
		{
			if (IsRunNian(y))
			{
				arr[1]=29;
			}
			else
			{
				arr[1]=28;
			}
			if (i>11)
			{
				i=0;
				y++;
			}
			tmp=tmp+arr[i];
			month=i+1;//数组标号从0开始,所以要加上1
		}
	}

	if (n>0) //算出天数
	{
		int tmp=0,y=1777;
		for(int i=4;tmp<n;i++)
		{
			day=n-tmp-1; //原来的代码为day=n-tmp,这让我很郁闷,
						//出生的那天过去了,算不算一天?
						//如果算,就要减去出生的那一天,
						//如果不算,就不要减一了。
						//根据题目给的5343,是:1791年12月15日。
						//得出出生的那天过去了也算是一天的。
			
			if (IsRunNian(y))
			{
				arr[1]=29;
			}
			else
			{
				arr[1]=28;
			}
			if (i>11)
			{
				i=0;
				y++; //下一年
			}
			tmp=tmp+arr[i];
		}
	
	}


	cout<<year<<" "<<month<<" "<<day<<endl;
}



int main(int argc, char* argv[])
{
	cout<<"\n出生的那天过去了,是5月0号,奇怪吧?算是个临界点吧!\n\n";
	CalcYMD(1);
	CalcYMD(5343);
	CalcYMD(8113);
	cin.get();
	return 0;
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//结果截图如下:


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

上面的代码感觉是不是有点长?其实还可以一次获取年、月、日的,优化后的代码如下:

#include "stdafx.h"
#include<iostream>
using namespace std;

//判断年份是否是闰年
bool IsRunNian(int year)
{
	if(year%400==0||(year%4==0&&year%100!=0))
		return true;
	else
		return false;
}


//高斯出生于:1777年4月30日
//判断高斯出生n天之后,是XXXX年XX月XX日
void CalcYMD(int n)
{
	int arr[]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的天数,二月未考虑闰年
	int year=1777,month=4,day=30; //高斯出生时的年、月、日
	int y=1777,tmp=0;
	
	for(int i=4;tmp<n;i++)
	{
		if (i>11)
		{
			i=0;
			y++; //下一年
		}
		if (IsRunNian(y))
		{
			arr[1]=29;
		}
		else
		{
			arr[1]=28;
		}
		day=n-tmp-1; //获取天数
		tmp=tmp+arr[i];
		year=y;  //获取年份
		month=i+1; //获取月份,注意月份编号从0开始
	}

	cout<<year<<" "<<month<<" "<<day<<endl;
}


int main(int argc, char* argv[])
{
	cout<<"\n出生的那天过去了,是5月0号,奇怪吧?算是个临界点吧!\n\n";
	CalcYMD(1);
	CalcYMD(5343);
	CalcYMD(8113);
	cin.get();
	return 0;
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

效果截图如下:


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


您的十分满意是我追求的宗旨。

您的一点建议是我后续的动力。








评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friendan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值