题目大意:

给出一个非负整数n。从1900年1月1日到1900+n-1年12月31日的这段时间里,某年某月13日可能为星期一至星期日的任何一种情况,求出星期一到星期日在规定时间内符合上述条件的数量,并输出。

思路:

简单模拟,思路见注释。

代码:

/*
ID: lujunda
PROG: friday
LANG: C++
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//total_days[i]表示到从1900年1月1日到1900+i年1月1日所需要的天数;week[i%7]表示星期i的数量;
int total_days[401],week[7];
//若leap[i]==true,则该1900+i年为闰年;
//若month[i]==true,则第i月为大月;
bool leap[401],month[13]={true,true,false,true,false,true,false,true,true,false,true,false,true};
//判断公历n年是否为闰年。若是闰年,返回true,否则返回false;
bool check_leap(int n)
{
	if((n%100&&n%4==0)||(n%400==0))
		return true;
	return false;
}
//初始化total_days,和leap数组;
void restore()
{
	int sum=0;
	for(int i=0;i<=400;i++)
	{
		leap[i]=check_leap(i+1900)?true:false;
		if(i)
			sum+=leap[i-1]?366:365;
		total_days[i]=sum;
	}
}
//计算第1900+n年1月1日到12月31日之间的星期一到星期日的数量,并将结果对应加到week数组上。
void cal(int n)
{
	int sum=total_days[n];
	//遍历12个月
	for(int i=1;i<=12;i++)
	{
		//i月13日
		week[(sum+13)%7]++;
		if(month[i])
			sum+=31;
		else if(i==2&&leap[n])
			sum+=29;
		else if(i==2)
			sum+=28;
		else
			sum+=30;
	}
}
int main()
{
	freopen("friday.in","r",stdin);
	freopen("friday.out","w",stdout);
	restore();
	int n;
	while(cin>>n)
	{
		memset(week,0,sizeof(week));
		//遍历每一年
		for(int i=0;i<n;i++)
			cal(i);
		for(int i=0;i<7;i++)
		{
			if(i)
				cout<<" ";
			cout<<week[(i+6)%7];
		}
		cout<<endl;
	}
}