Problem N :输出月历(II)
Description
输出公元1900 ~ 2200年之间任意月的月历。 |
Input
输入若干行,至EOF结束,每行两个整数,分别表示年和月。 |
Output
对应输入顺序输出月历,两个月历之间有一个空行。 每个月历的第一行为表头"Sun Mon Tue Wen Thu Fri Sat",表示星期日 ~ 星期六。第二行开始的每行为一个星期,把每月的1日 ~ 结尾一日对应阿拉伯数字填入其中。每列占3个字符,其中的数字右对齐,每两列之间一个空格分隔,每行最后一个数字后面不要有空格。最后一日后面不要有空格。 |
这道题不是很难,但是有点复杂,对于初学者来说,还是有一定的难度的,计算日期的有许多算法,其中最有效的就是蔡勒公式,感兴趣的可以去看下,在这里我就不做介绍了,我的想法是确定一个已知的年和月,然后通过它来推算出所要求的年月的第一天,知道这些之后,直接打印就好了。还有最重要的,不要忘记了格式的控制哦!!!话不多说,直接上代码吧。如有错误,还请大佬们多多指正。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*输出表头*/
void pr()
{
printf("Sun Mon Tue Wen Thu Fri Sat\n");
}
int mo[3][13]= {0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};
/*判断是否是闰年*/
int judje(int i)
{
if(i%4==0&&i%100!=0||i%400==0)
return 1;
return 0;
}
int ju[500][3];
int flag=1;/*每个月的第一天是周几*/
int main()
{
for(int i=0,j=1900; j<=2202; i++,j++){
ju[i][0]=j;
ju[i][1]=judje(j);
}
int k,l;
while(scanf("%d%d",&k,&l)){
pr();
long long sum=0;
for(int i=0; i<k-1900; i++){
if(ju[i][1])
sum+=366;
else
sum+=365;
}
/*记录所要求的月份的第一天*/
int kk=ju[k-1900][1];//是否是闰年
for(int i=1; i<l; i++)
sum+=mo[kk][i];
flag=sum%7+1;
//cout<<flag<<endl;
/*所求月的天数*/
int day=mo[kk][l];
int p=0;
if(flag!=7){
for(int i=0; i<flag*4-1; i++){
printf(" ");
p=1;
}
}
else{
p=0;
}
/*按格式输出*/
for(int i=1; i<=day; i++){
if(p){
printf("%4d",i);
}
else{
printf("%3d",i);
p=!p;
}
if((!((i+flag)%7))&&i!=day){
printf("\n");
p=0;
}
}
printf("\n\n");
}
return 0;
}