Problem 19 Counting Sundays

Problem

You are given the following information, but you may prefer to do some research for yourself.

  • 1 Jan 1900 was a Monday.
  • Thirty days has September,
    April, June and November.
    All the rest have thirty-one,
    Saving February alone,
    Which has twenty-eight, rain or shine.
    And on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

分析

统计从1901.1.1 到 2000.12.31 号,当月的第一天是星期天的次数。

方法:题目给出这些提示的意思,应该是让我们自己算,而不是调用库函数去实现。当然,用库函数去实现确实是一个更简单快捷的方法。

C\C++

方法1 从1901.1.1 往后,每过一天,week++,如果week是星期天,且当天为1号,则cnt++。

[cpp]#include <stdio.h>

/*返回year年month月的天数*/
int get_days(int year,int month)
{
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
{
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else if(month == 2)
{
//判断是否是闰年
if ((year%4 == 0 && year%100 != 0) || year%400 ==0) //闰年,能被4整除同时不能被100整除,或者能被400整除
{
return 29;
}
else
{
return 28;
}
}
else
{
printf("Error!\n");
return -1;
}
}

int main(int argc, char* argv[])
{
int year,month,day;
int days_one_month;

int cnt = 0; //记录月第一天是星期天的次数
int week = 1 ; //1 表示星期1,...7 表示星期天 (初始化为1900.1.1 为星期1)

for (year=1900;year<=2000;year++)
{
for (month=1;month<=12;month++)
{
days_one_month = get_days(year,month); //获取当月的天数

for (day=1;day<=days_one_month;day++)
{
//printf("%d-%d-%d %d\n",year,month,day,week);
if(week == 7 && day == 1 && year>=1901) //星期天在当月的第1天(1901年以后)
{
//printf("%d-%d-%d\n",year,month,day);
cnt++;
}
week++; //每过一天,星期++
if(week==8) week=1;
}
}
}

printf("%d\n",cnt);
return 0;
}[/cpp]

year,month,day 分别代表年月日,年从1900年开始走,(因为已知1900.1.1 是周一),月从1~12,日由get_days(year,month)函数获取。week 表示当天是星期几。如果当天是星期天,而且是当月1号,而且是1901年之后的(因为1900年的不用统计),则cnt++。每当week==8时,重置为1.(当然也可以取模实现)

get_days(year,month)函数返回year年month月的当月的天数。1,3,5,7,8,10,12月每月31天;4,6,9,11每月30天,闰年2月29天,非闰年28天。

Python

方法1 使用calendar模块, 一行代码

[python]import calendar
count = 0
for y in range(1901,2001):
for m in range(1,13):
w = calendar.weekday(y,m,1)
if w==6: #6 stards for sunday
count += 1
#print y,'-',m,'-1'
print count[/python]

calendar.weekday(year,month,day)方法返回当天是星期几。也可以改写成如下一行代码

[python]print sum([1 for y in range(1901, 2001) for m in range(1, 13) if calendar.weekday(y, m, 1) == 6])[/python]

当月1号为星期天时,列表中添加一个1,最后统计列表的和。

答案

171

知识点

  • Python calendar 模块

作者:JarvisChu
原文链接:Problem 19 Counting Sundays
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

发表评论