题如下:来自c语言网(蓝桥杯ACM训练系统 - C语言网)
已知2007年1月1日为星期一。
设计一函数按照下述格式打印2007年以后(含)某年某月的日历,2007年以前的拒绝打印。
为完成此函数,设计必要的辅助函数可能也是必要的。其中输入为年分和月份。
注意:短线“-”个数要与题目中一致,否则系统会判为错误。
样例输入:
2010 9
样例输出:
--------------------- Su Mo Tu We Th Fr Sa --------------------- 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 ---------------------
解题思路:
1:当year=2007时,怎么处理
定义一个函数,用于处理需要单独处理的年;
2:如何处理2007<=n<=year-1的日期
定义一个函数,用于处理中间的整年
3:当n来到year时,怎么处理;
定义一个函数,用于处理需要单独处理的年;
4:如何处理闰年、平年;
定义一个判断函数;
5:如何处理二月
- 处理单独年时,注意当month=2是,要进行减一处理
- 处理中间按年份是,当判断是平年时,要进行减一处理
6:如何找到规律
2007 1 1为周一,与之对应,2007 1 7为周日,则可以通过从2007 1 1开始对天数进行求和得到sum,sum%7即是周几,考虑到表头问题,当进行sum%7+1处理即可
话不多说,上代码和注释:
#include<stdio.h>
int judge(int year)//判断闰年或平年
{
if((year%4==0&&year%100!=0)||year%400==0) return 1;
return 0;
}
int Sum1(int year,int date[]) //处理2007——year-1的日期
{
int sum=0;
for(int i=0;i<12;i++)
{
sum+=date[i];
}
if(!judge(year))//平年一整年下来比闰年少一天
{
sum-=1;
}
return sum;
}
int Sum2(int year,int month,int date[])//用于处理2007和year 年
{
int sum=0;
if(month==1)//处理月份时第一月的情况
{
sum=0;
}
else{
for(int i=0;i<month-1;i++)
{
sum+=date[i];
}
if(!judge(year)&&month!=2) sum-=1;//此处很细节(二月单独的处理)
}
return sum;
}
int main()
{
int year,month,i,sum=0;
int date[12]={31,29,31,30,31,30,31,31,30,31,30,31};
scanf("%d %d",&year,&month);
if(year>=2007)
{
if(year==2007)//单独处理2007年时的情况
{
sum=Sum2(year,month,date);
}
else{
for(i=2007;i<year;i++)//处理从2007到year-1年的情况
{
sum+=Sum1(i,date);
}
if(Sum2(year,month,date))
{
sum+=Sum2(year,month,date);
}
}
sum+=1;//以上得到的sum 是从2007 1开始到year month-1 的所有天数之和,加1跳到下一个月(即month)的第一天
int index=sum%7,flog=0;//余7处理用于和表头对上Su 1 ,Mo 2,Tu 3......,Sa 6;flog用于计数换行,满7置为0,并换行
printf("---------------------\n");
printf(" Su Mo Tu We Th Fr Sa\n");
printf("---------------------\n");
for(i=0;i<index;i++)//对第一行处理
{
if(i!=index)//第一行空的地方统一是3个空格
{
printf(" ");
flog++;
}
}
if(!judge(year))//此处对于2月的天数进行矫正(不然始终会是29天,当year是平年且month=2时打印的日历多一天)
{
date[1]--;
}
for(i=0;i<date[month-1];i++) //从1打印 到本月最大天数
{
printf("%3d",i+1);//对于%nd没有概念的朋友请自行解决
flog++;
if(flog==7)
{
flog=0;
if(i!=date[month-1]-1)
{
printf("\n");
}
}
}
printf("\n---------------------");
}
return 0;
}
总结;此类题为日期题,易错点在于对于2月的细致化处理。
(每天提醒一次自己,不要当废物!)