天天看點

藍橋杯 高斯日記

網上給的都是結果,代碼我來給吧。

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

題目标題: 高斯日記

    大數學家高斯有個好習慣:無論如何都要記日記。

    他的日記有個與衆不同的地方,他從不注明年月日,而是用一個整數代替,比如: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;
}
           

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

效果截圖如下:

藍橋杯 高斯日記

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

藍橋杯 高斯日記

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

您的一點建議是我後續的動力。