5.3日历问题

问题描述:


在我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它们不是闰年。

例如:
1700, 1800, 1900 和 2100不是闰年,而 1600, 2000 和 2400是闰年。给定从公元2000年1月1日开始逝去的天数,你的任务是给出这一天是哪年哪月哪日星期几。


输入数据
输入包含若干行,每行包含一个正整数,表示从
2000年1月1日开始逝去的天数。


输入最后一行是-1, 不必处理。可以假设结果的年份不会超过9999。
输出要求
对每个测试样例,输出一行,该行包含对应的日期和星期几。格式为
“YYYY-MM-DD


DayOfWeek”,其中 “DayOfWeek” 必须是下面中的一个: "Sunday", "Monday",
"Tuesday", "Wednesday", "Thursday", "Friday" and "Saturday“。
输入样例

1730
1740
1750
1751
-1

输出样例

2004-09-26 Sunday
2004-10-06 Wednesday
2004-10-16 Saturday

2004-10-17 Sunday


解题思路


这道题目使用的背景知识是闰年的定义和公历日历中一年12个月中每个月的日期数。


根据题目要求,所有涉及的数值都是用整数可以表示的。这个问题可以分解成两个彼此独立的问题:一个是要求的那天是星期几,另一是要求的那天是哪年哪月那天。第一个问题比较简单,知道2000年1月1日是星期几后,只要用给定的日期对7取模,就可以知道要求的一天是星期几。第二个问题相对麻烦一些。

我们用year, month, date分别表示要求的日期的年、月、日。当输入一个整数n时,如果n大于等于一年的天数,就用n减去一年的天数,直到n比一年的天数少(这时假设剩下天数为m),一共减去多少年year就等于多少;如果m大于等于一个月的天数,就用m减去一个月的天数,直到m比一个月的天数少(这时假设剩下的天数为k),一共减去多少个月month就等于多少;这时k为从当月开始逝去的天数,k+1就是要求的date。这里减去一年的天数时要判断当年是否是闰年,减去一月时要判断当月有几天。

代码如下:

/* * *Declaration:The author of <<Accelerated C++>> has wrote in the end of that book: As you look for reading materimal, keep in mind that books on the shelf do not make you a better programmer. Ultimately, the only way to improve your programming is to write programs. >这些程序来自一些ACM书籍,作者只为提高编程能力,实现书中例题或练习。如有侵权,请联系作者,作者将立即删除。 * *联系邮箱:mingxinglai#gmail.com * */ #include <stdio.h> int type(int); char week[7][10] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; int year[2]= {365, 366}; int month[2][12] = {31, 28, 31, 30, 31, 30, 31, 31, 30,31, 30, 31,31, 29, 31, 30, 31, 30, 31, 31, 30,31, 30, 31}; int main(int argc, char* argv[]) { int days, dayofweek; int i = 0, j = 0; while( scanf("%d", &days) && days != -1) { dayofweek = days % 7; for( i = 2000; days >= year[type(i)]; i++) days -= year[type(i)]; for( j = 0; days >= month[type(i)][j]; j++) days -= month[type(i)][j]; //尤其注意这一行代码,要是我自己,还会单独计算年月日,可见经验之匮乏 printf("%d-%02d-%02d %s\n", i, j + 1, days + 1, week[dayofweek]); } return 0; } int type( int m) { if( m % 4 != 0 || ( m % 100 == 0 && m % 400 != 0 )) return 0; else return 1; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值