2013第三届蓝桥杯C/C++本科预赛1 高斯日记
2014-03-21 15:06
295 查看
题目:
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
1,一般解法,将全部天数分为三个部分
[1]出生日1777-4-30到1777-12-31的天数(已知)
[2]1778-1-1到某年年底的天数,这部分时间成为完整的年(闰年共366,平年365)
[3]减去以上时间后剩余天数不足一年,这时计算这一年中的某一天。
输出结果为
与样例多了一天,题意是将出生日为第一天,即应该减去一天。
修改程序后,本题的正确结果为:
注意提交格式。
2, 解法2,求两个日期的间隔天数。
已知1777-4-30到某年某月某日的天数为8113,可以求 1777-4-30到特定的年月日的天数,不断改变后一个日期以使j间隔天数到达8113即可,实际是求两个日期间隔的天数,如: 求 1777-4-30到1791-12-15相隔的天数。采用的是后一个日期减去前一个日期的想法。
1777其实不满一年,它只有3个月+30天,使用 1791年的12月15日(其实是11个月+15日)减去这部分时间么?防止后一个日期不足一年的时间小于前一个日期不足一年的时间,最好从1791以前挪用一年的时间+1791不足一年的时间-前一个日期1777不足一年的时间。
[1]1790整年的时间+12月15日(1791年) - 4月30日(1777年)
[2]再用1789年 - 1777年,就是 1777到 1789的时间。
以上[1][2]部分时间相加后即为所求的日期相隔时间。
是的,与样例依然相差了一天,应该将出生了那天计算在内。
这时与所求仍然有距离,题已知的是距离所知日期的天数:8113
看到 8113 - 5343 = 2770; 大约相差7年,更改日期的年数
int curYear = 1798, curMonth = 12, curDay = 15;
输出:
8113 - 7899相差了214天,由于已经是12月,必须增加年数。
int curYear = 1799, curMonth = 12, curDay = 15;
输出:
8264 - 8113多了 151天,差不多5个月,于是再次更改
int curYear = 1799, curMonth = 7, curDay = 15;
输出:
结果少了2天,
再次更改:
int curYear = 1799, curMonth = 7, curDay = 17;
输出:
尝试终得结果,但是莫忘用例中必须加上出生那天,所以我们的结果应该是8112,最终的答案是:
1799-7-16
注意提交格式
3,在解法2的的基础上,两个日期间隔相当于在数轴上的两个非负数的点A,B,可以简单的用B-A等于之间相隔的距离。某个日期在轴上的位置,如1791-12-15:0年1月1日(元年0开始还是1开始?这不重要)到1790年12月31日 + 11月30天(1791)
哈,答案正确。
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21
1,一般解法,将全部天数分为三个部分
[1]出生日1777-4-30到1777-12-31的天数(已知)
[2]1778-1-1到某年年底的天数,这部分时间成为完整的年(闰年共366,平年365)
[3]减去以上时间后剩余天数不足一年,这时计算这一年中的某一天。
#include <iostream> using namespace std; int MONTH[] ={0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 0月不存在,2月置0 // 判断闰年 bool IsLeapyear(int year) { if(year % 400==0 || (year%4==0 && year%100!=0)) return true; else return false; } // 月份天数 int Month(int year, int month) { int monthDays; if(month != 2) monthDays = MONTH[month]; else monthDays = IsLeapyear(year) ? 29 : 28; return monthDays; } // 第一部分:某日到年底天数 int DaysToNextYear(int year, int month, int day) { int days1 = 0, days2 = 0; // 某日到年底的天数 = 当日到月尾的天数 + 下月到12月底的天数 days1 = Month(year, month) - day; for(int i = month+1; i <= 12; i++) days2 += Month(year, i); return (days1 + days2); } // 第二部分:凑成的完整年的天数 int DaysInFullYear(int sartYear, int nYears) { int days = 0; for(int i = sartYear; i < sartYear+nYears; i++) { days += (IsLeapyear(i)?366:365); } return days; } // 第三部分:求余下的天数是某一日 int Date(int year, int days) { int i; for(i = 1; i <= 12; i++) { if (days > Month(year, i)){ days -= Month(year, i); } else break; } cout<<"Time: "<<year<<"-"<<i<<"-"<<days<<endl; } int main(void) { // part1 int allDays = 5343, days1, days2; int year = 1777, month = 4, day = 30; days1 = DaysToNextYear(year, month, day); days2 = DaysInFullYear(year+1, (allDays-days1)/365); Date(year + 1 + (allDays-days1)/365, allDays - days1 - days2); return 0; }
输出结果为
与样例多了一天,题意是将出生日为第一天,即应该减去一天。
修改程序后,本题的正确结果为:
注意提交格式。
2, 解法2,求两个日期的间隔天数。
已知1777-4-30到某年某月某日的天数为8113,可以求 1777-4-30到特定的年月日的天数,不断改变后一个日期以使j间隔天数到达8113即可,实际是求两个日期间隔的天数,如: 求 1777-4-30到1791-12-15相隔的天数。采用的是后一个日期减去前一个日期的想法。
1777其实不满一年,它只有3个月+30天,使用 1791年的12月15日(其实是11个月+15日)减去这部分时间么?防止后一个日期不足一年的时间小于前一个日期不足一年的时间,最好从1791以前挪用一年的时间+1791不足一年的时间-前一个日期1777不足一年的时间。
[1]1790整年的时间+12月15日(1791年) - 4月30日(1777年)
[2]再用1789年 - 1777年,就是 1777到 1789的时间。
以上[1][2]部分时间相加后即为所求的日期相隔时间。
#include <iostream> using namespace std; int MONTH[] ={0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 0月不存在,2月置0 // 判断闰年 bool IsLeapYear(int year) { if(year % 400==0 || (year%4==0 && year%100!=0)) return true; else return false; } // 某年的天数 int DaysYear(int year) { if(IsLeapYear(year)) return 366; else return 365; } // 某年月初(1月1日)到某月某日的天数 int DaysDate(int year, int month, int day) { int days = 0; // 先计算该月前的天数 for(int i = 1; i <= month-1; i++) days += MONTH[i]; // 另外计算2月 if(IsLeapYear(year)) days+=29; else days+=28; // 加上该月的天数 days += day; return days; } int main(void) { int preYear = 1777, preMonth = 4, preDay = 30; //int curYear = 1791, curMonth = 12, curDay = 15; int curYear = 1799, curMonth = 7, curDay = 15; int days1 = 0, days2 = 0, days3 = 0, days4 = 0; // 1790整年时间 days1 = DaysYear(curYear-1); // 1791年的天数, 11个月+30天 days2 = DaysDate(curYear, curMonth, curDay); // 1 1790整年的时间+12月15日(1791年) - 4月30日(1777年) days3 = days1 + days2 - DaysDate(curYear, preMonth, preDay); // 2 1789年(12月31日) - 1777年(1月1日), 也等于1777年到1789年的天数 for(int i = preYear; i<=curYear-2; i++) days4 += DaysDate(i, 12, MONTH[12]); // 两个年月日之间的天数 cout<< days3 + days4<<endl; }输出结果:
是的,与样例依然相差了一天,应该将出生了那天计算在内。
这时与所求仍然有距离,题已知的是距离所知日期的天数:8113
看到 8113 - 5343 = 2770; 大约相差7年,更改日期的年数
int curYear = 1798, curMonth = 12, curDay = 15;
输出:
8113 - 7899相差了214天,由于已经是12月,必须增加年数。
int curYear = 1799, curMonth = 12, curDay = 15;
输出:
8264 - 8113多了 151天,差不多5个月,于是再次更改
int curYear = 1799, curMonth = 7, curDay = 15;
输出:
结果少了2天,
再次更改:
int curYear = 1799, curMonth = 7, curDay = 17;
输出:
尝试终得结果,但是莫忘用例中必须加上出生那天,所以我们的结果应该是8112,最终的答案是:
1799-7-16
注意提交格式
3,在解法2的的基础上,两个日期间隔相当于在数轴上的两个非负数的点A,B,可以简单的用B-A等于之间相隔的距离。某个日期在轴上的位置,如1791-12-15:0年1月1日(元年0开始还是1开始?这不重要)到1790年12月31日 + 11月30天(1791)
int main(void) { int preYear = 1777, preMonth = 4, preDay = 30; int curYear = 1791, curMonth = 12, curDay = 15; int days1 = 0, days2 = 0, days3 = 0; // 元年是0年还是1年呢,这不重要 // 1 0年 - 1777年 + 4月30在这年的时间 for(int i = 0; i <= preYear-1; i++) days1 += DaysYear(i); days1 += DaysDate(preYear, preMonth, preDay); // 2 0年 - 1791年 + 12月15在这年的时间 for(int i = 0; i <= curYear-1; i++) days2 += DaysYear(i); days2 += DaysDate(curYear, curMonth, curDay); cout<<days2 - days1<<endl; return 0; }输出:
哈,答案正确。
相关文章推荐
- 2013 蓝桥杯 2013预赛C本科-A组 所有试题解析,高斯日记+排它平方数+振兴中华+颠倒的价牌+前缀判断+逆波兰表达式+买不到的数目+剪格子+大臣的旅费
- 夺冠概率--第三届蓝桥杯预赛真题 c++本科组 第9题(我用java做的)
- 2013第四届蓝桥杯预赛试题本科c++三部排序
- 2013第四届蓝桥杯预赛试题本科c++第39级台阶
- 取球游戏--第三届蓝桥杯预赛真题 c++本科组 第10题(我用java做的)
- “蓝桥杯”第四届本科B组预赛试题: 高斯日记
- 2013蓝桥杯预赛C/C++本科B组解题报告
- “蓝桥杯”第四届本科B组预赛试题: 高斯日记
- 2013第四届蓝桥杯预赛试题本科c++马虎的算式
- 密码发生器--第三届蓝桥杯预赛真题 c++本科组 第8题(我用java做的)
- 蓝桥杯 第四届C/C++预赛真题(1) 高斯日记(数学题,年份处理)
- 2013第四届蓝桥杯预赛试题本科c++前缀判断
- 蓝桥杯 第三届C/C++预赛真题(6) 大数乘法(数学题)
- 2012第三届蓝桥杯 C/C++本科组真题及题解(未完待续)
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 打印图形
- 2014 第五届蓝桥杯预赛c/c++本科B组 解题报告
- 高斯日记-第四届蓝桥杯c/c++B组
- 2013第四届 蓝桥杯c/c++B组预赛 解题报告(还在更新中。。。。。)
- [JAVA][2013蓝桥杯预赛 JAVA本科B组][振兴中华]
- 蓝桥杯试题与分析(第四届C/C++本科A组预赛)