百练 打印日历(日期问题)

时间:2022-08-19 14:01:14

打印月历

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

给定年月,打印当月的月历表。

输入
输入为一行两个整数,第一个整数是年份year(1900 ≤ year ≤ 2099),第二个整数是月份month(1 ≤ month ≤ 12),中间用单个空格隔开。
输出
输出为月历表。月历表第一行为星期表头,如下所示:
Sun Mon Tue Wed Thu Fri Sat
其余各行一次是当月各天的日期,从1日开始到31日(30日或28日)。
日期数字应于星期表头右对齐,即各位数与星期表头相应缩写的最后一个字母对齐。日期中间用空格分隔出空白。
样例输入
2006 5
样例输出
Sun Mon Tue Wed Thu Fri Sat
      1   2   3   4   5   6
  7   8   9  10  11  12  13
 14  15  16  17  18  19  20
 21  22  23  24  25  26  27
 28  29  30  31
提示
闰年判断方法:能被4整除但不能被100整除,或者能被400整除。
1900年1月1日是周一。

tips:输出1900年以后的每个月的日历表。关键是要确定当前月的1号是周几。
1.统计月初到1900年1月1日中间有多少天。记为cnt;
2.cnt%7  余数为周几,特别的周日的余数为0
3.统计第一行的天数,记为t;
4.根据规律打印,若(i-t-1)%7==0 每行的第一个数,占据三位。若(i-t)%7==0最后一个数,打印换行。
#include<iostream>
#include<cstring>

using namespace std;

int y,m;
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

int cnt;
bool leap(int x)
{
	return (x%400==0)||(x%4==0&&x%100!=0); 
}
int main()
{
	cin>>y>>m;
	cout<<"Sun Mon Tue Wed Thu Fri Sat"<<endl;
	
	for(int i=1900;i<y;i++)
	{
		if(leap(i))cnt+=366;
		else cnt+=365;
	}
	if(leap(y))month[2]++;
	
	for(int i=1;i<m;i++){
		cnt+=month[i];
	}
	
	int t=0;
	(cnt++)%=7;
	for(int i=0;i<cnt;i++)cout<<string(4,' ');
	
	for(int i=cnt;i<=6;i++){
		t++;
		if(i==cnt)printf("%3d",t);
		else printf("%4d",t);
	}
	cout<<endl;
	for(int i=t+1;i<=month[m];i++)
	{
		if((i-t-1)%7==0)printf("%3d",i);
		else printf("%4d",i);
		
		if((i-t)%7==0)cout<<endl;
	}
	
	return 0;
}