2020-12-31 输出月历

输出月历有两种题型,第一种是给定这个是月一号是星期几,然后输出对应的月历,第二种是给一个1900年后的特定年月输出对应的月历。

第一种题型无非就是简单的控制输出(为啥我老喜欢写控制输出的题型的博客啊),第一种输出掌握好,第二种题型无非就是将对应的年月转化为第一种题型中所需要我周几就可以了,所以第二种题型是建立在第一种题型基础上的算法题。

输出月历(Ⅰ)

#include<stdio.h>
int main()
{
    int n,i,j;
    scanf("%d",&n);
    printf("Sun Mon Tue Wen Thu Fri Sat\n");
    if((n>=0)&&(n<=6))
        for(i=1;i<=4*n;i++)
            printf("%c",' ');
    for(i=n,j=1;j<=30;j++)
    {
        i++;
        if((j==1)||(i%7==1))printf("%3d",j);
        else printf("%4d",j);
        if(i%7==0)
            printf("\n");
    }


}

首先是输出头行,这个不用多说。

第二个是将输入的数作为周几,加入输出计数器中,使得每输出到周六时就可以换行。

第三,设置一个单独的变量,输出这是几号。

第四,为了使输出对齐,用取余的方法判断这是一行中第几个数,如果不是第一个数就多输出一个空格,第七个输出之后输出换行符。

输出月历(Ⅱ)

这个题分为三个过程:第一步,判断平闰年;第二步,判断这个月一号是周几;第三步,输出月历。

第一步:

基本规则:能被4整除但不能被100整除的是闰年,能被400整除的是闰年

int judge_y(int y)
{
    if((y%4==0&&y%100!=0)||y%400==0)
        return 1;
    else
        return 0;
}

第二步:

也是这个题最难的地方

可以说这是一个计算题。了解到的是,1900年1月1日是星期一,这就为做题提供初始值,然后就把所有的天数加起来,再取7的余数,就是星期几了。

int judge_w(int y,int m)
{
    int day,w;
    y--;
    day=(y-1899)*365+y/4-y/100+y/400-460+1;
    for(int i=1; i<=m-1; i++)
        day+=mo[i];
    w=day%7;
    return w;
}

这里需要注意的一点就是,因为1900到所要求的年份中间可能存在闰年,我们可以把所有的年分都按照平年计算,然后加上闰年的年数,就可以得到所求的年数了。

第三步:

void print(int w,int n)
{
    printf("Sun Mon Tue Wen Thu Fri Sat\n");
    for(int i=1; i<=w*4-1; i++)
        putchar(' ');
    for(int i=1+w,j=1; j<=n; i++,j++)
    {
        if(i%7==1)
            printf("%3d",j);
        else if(i%7==0&&j<n)
            printf("%4d\n",j);
        else
            printf("%4d",j);
    }
    printf("\n\n");
}

前面讲了,这里不再多说。

代码全貌:

#include<stdio.h>
int mo[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int judge_y(int y)
{
    if((y%4==0&&y%100!=0)||y%400==0)
        return 1;
    else
        return 0;
}
int judge_w(int y,int m)
{
    int day,w;
    y--;
    day=(y-1899)*365+y/4-y/100+y/400-460+1;
    for(int i=1; i<=m-1; i++)
        day+=mo[i];
    w=day%7;
    return w;
}
void print(int w,int n)
{
    printf("Sun Mon Tue Wen Thu Fri Sat\n");
    for(int i=1; i<=w*4-1; i++)
        putchar(' ');
    for(int i=1+w,j=1; j<=n; i++,j++)
    {
        if(i%7==1)
            printf("%3d",j);
        else if(i%7==0&&j<n)
            printf("%4d\n",j);
        else
            printf("%4d",j);
    }
    printf("\n\n");
}
int main()
{
    int y,m;
    while(scanf("%d%d",&y,&m)!=EOF)
    {
        int j,n;
        j=judge_y(y);
        if(j==1)
            mo[2]=29;
        if(j==0)
            mo[2]=28;
        n=mo[m];
        int w;
        w=judge_w(y,m);
        print(w,n);
    }

}

这道题看似特别难,但是思考过来,这题的难点在哪呢?无非就是见到这个题之后被吓到,认为自己做不出来而已,但是,题目本身没有非常繁琐的过程,全是简单的代码,难就难在,怎么把它串成一条思路。敢做,敢尝试,自信,别畏手畏脚,放手去尝试,其实结果会比想象地简单得多。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值