Project Euler 题解 #19 Counting Sundays

题目:Counting Sundays

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)?

解题思路

蔡勒公式:一种计算任何一日属一星期中哪一日的算法。

这个公式太牛B了,没看的很明白。

参考下这几个:

蔡勒公式的由来

求某一天是星期几

星期的计算

代码实现

//https://projecteuler.net/problem=19
//Counting Sundays

#include <cassert>
#include <iostream>

using namespace std;

const char *DayInWeek[] = {"momday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};

//返回值
//0:星期一
//...
//6:星期天
int DayOfWeek(int year, int month, int day)
{
	assert(year >  0);
	assert(1 <= month && month <= 12);
	assert(1 <= day && day <= 31);
	int dayofweek = 0;

	if (month == 1 || month == 2)
	{
		month += 12;
		year--;
	}
	if ((year < 1752) || (year == 1752 && month < 9) || (year == 1752 && month == 9 && day < 3))
	{
		dayofweek = (day + 2*month + 3*(month + 1)/5 + year + year/4 + 5)%7;
	} 
	else
	{
		dayofweek = (day + 2*month + 3*(month + 1)/5 + year + year/4 - year/100 + year/400)%7;
	}

	return dayofweek;
}


int _tmain(int argc, _TCHAR* argv[])
{
	cout<<DayInWeek[DayOfWeek(2013, 9, 27)]<<endl;

	int count = 0;
	for (int year = 1901; year <= 2000; ++year)
	{
		for (int month = 1; month <= 12; ++month)
		{
			if (6 == DayOfWeek(year, month, 1))
			{
				++count;
			}
		}
	}

	cout<<"There are "<<count<<" Sundays fell on the first of the month during the twentieth century"<<endl;

	system("pause");
	return 0;
}

输出:171


有位读者提出公式1200/7 = 171

可见数学的魅力所在。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值