编写万年历

1.目的:
 培养逻辑思维的严密性
 提高利用C语言进行程序设计的能力
2.要求:
(1)输入年份,判断是否为闰年
(2)输入年月日,判断是星期几
(3)输入年份,打印出12个月的月历
(4)输入年月,打印出本月的日历


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
void runnian(int year1)
{
   
    if (year1 % 4 != 0)
        printf("%d年不是闰年\n", year1);
    else if (year1 % 100 == 0 && year1 % 400 != 0)
        printf("%d年不是闰年\n", year1);
    else
        printf("%d年是闰年\n", year1);
}
void xinqi(int iY, int iM, int iD)
{
   
    int iWeekDay = -1;
    if (1 == iM || 2 == iM)
    {
   
        iM += 12;
        iY--;
    }
    iWeekDay = (iD + 1 + 2 * iM + 3 * (iM + 1) / 5 + iY + iY / 4 - iY / 100 + iY / 400) % 7;
    switch (iWeekDay)
    {
   
    case 0:
        cout << "Sunday\n";
        break;
    case 1:
        cout << "Monday\n";
        break;
    case 2:
        cout << "Tuesday\n";
        break;
    case 3:
        cout << "Wednesday\n";
        break;
    case 4:
        cout << "Thursday\n";
        break;
    case 5:
        cout << "Friday\n";
        break;
    case 6:
        cout << "Saturday\n";
        break;
    }
}
void yueli(int n)
{
   
	int a,b,c,xinqi,i,j,num,temp1,temp2,temp3;
	a = n/100;
	b = n/4;
	c = (n+b-a)%7;
	if(c<=2)
	xinqi = c+5-((n%4==0)&&(n%100!=0)||(n%400==0));
	else
	{
   
		xinqi = c-2-((n%4==0)&&(n%100!=0)||(n%400==0));
		if(xinqi == 0)
		xinqi = 7;
	}
	
	for(i = 1; i <= 12; i++)
	{
   
		printf("Sun Mon Tue Wed Thu Fri Sat\n");
		
		temp1 = 1;
		
		if(i==2)
		num = 28+((n%4==0)&&(n%100!=0)||(n%400==0));
		else if(i%2 != 0)
		{
   
			if(i >=1 && i<= 7)
			num = 31;
			else
			num = 30;
		}
		else if(i%2 == 0)
		{
   
			if(i >= 4 && i <= 6)
			num = 30;
			else
			num = 31;
		}
		
		if(xinqi == 7)
		{
   
			temp2 = 0;
			temp3 = 7;
			xinqi = num%7;
		}
		else
		{
   
			temp2 = 4*xinqi;
			temp3 = 7-xinqi;
			xinqi = num+xinqi-28;
			if(xinqi>7)
			xinqi = xinqi%7;
		}

		for(j = 1; j <= temp2; j++)
		printf(" ");
		
		while(temp1 <= num)
		{
   
			printf("%3d ",temp1++);
			if(temp1==temp3+1 || temp1==temp3+8 || temp1==temp3+15 || temp1==temp3+22 || temp1==temp3+29)
			printf("\n");
		}
		cout<<endl;
	}
} 
int ps(int x,int y)
{
   
	if(y==2)
		if((x%4==0&&x%100!=0)||(x%400==0))
			return 29;
		else
			return 28;
	else if(y==1||y==3||y==5||y==7||y==8||y==10||y==12)
		return 31;
	else
		return 30;
}//判断每月的天数
void rili(int y, int m)
{
   
    printf("Sun Mon Tue Wed Thu Fri Sat\n");//打印月历的开头
	int k=1;
	for(int i=1900;i<y;i++)
		if((i%4==0&&i%100!=0)||(i%400==0))
			k+=366;
		else
			k+=365;
	for(int j=1;j<m;j++)
		k+=ps(y,j);
	k=k%7;//计算第y年m月1号是周几
	int t=0,p=0;//两个临时变量
	for(int i=1;i<=ps(y,m);i++)//循环到当月的最后一天
	{
   
		if(p==0)//用p来看是否已经打印过第一排才打印的空格
		{
   
			for(int j=0;j<(k)*4;j++)
				printf(" ");//打印空格
			p=1;
		}
		printf("%3d ",i);//控制格式并打印
		t++;
		if(t+k==7)//如果一排打印完了
		{
   
			printf("\n");//打印换行
			t=0;
			k=0;//一定要清零
		}
	}
}

int main()
{
   
    int n, y, r;
    cin >> n >> y >> r;
    runnian(n);
    xinqi(n, y, r);
    yueli(n);
    rili(n, y);
    return 0;
}