一、题目
【问题描述】
输入年份和月份, 输出该月的月历。
【输入形式】
输入包含两个整数Y(Y>1920)和M(1<=M<=12),分别表示年份和月份
【输出形式】
阵列式月历,数字间用空格分隔。
【样例输入】
2016 11
二、思路:
开始是想一个一个找,用二维数组把每个数字都变一下。后面发现可以只找一个“定位1”,即只要找到这个月份的一号。观察日历,发现有两个小规律:
规律一:
与上年相比,今年的一月一号比上一年星期上多了一天或多两天,即:如果去年一月一号是周二且去年是平年,今年一月一号就是周三。如果是闰年,今年一月一号就是周四。
规律二:
与上个月相比,这个月的一号比上个月星期上多了0~3天,即如果上个月有28天,这个月的一号和上个月一号的星期相同,29天就+1,30天就+2;31天就+3;
三、代码实现
1.有了这两个规律,就很好写了。先来两个会用到的函数,判断闰年和计算某年某个月有多少天
bool leap_year(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true; //是闰年
}
return false;
}
int cal_day(int year,int month) { //计算当月有多少天
int result = 0;
int kk[12] = { 31 ,28,31,30,31,30,31,31,30,31,30,31 }; //bug1:kk初始化已经固定,不会被temp的变化修改
if (leap_year(year) && month == 2) return 29;
else result = kk[month - 1];
return result;
}
2.初始处理,因为题目的数据是从Y>1920,我就把1921年一月一号作为所有数据的开始;
另外先把第一行输出了。
main外我定义了个二维数组,在这里也给它初始化一下,方便最后输出时遇到0就输出空格
int arr[6][7];
int Y, M;
cin >> Y >> M;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
arr[i][j] = 0;
}
}
cout << "Sun Mon Tus Wed Thu Fri Sat" << endl;
int location_x = 0,location_y =6, year =1921,month = 1,day =1; //该月天数,1921年一月一号的位置
3.先找这一年的一号,再找这一月的一号
//找到当年一月一号的位置
while (year < Y) {
if (leap_year(year)) {
location_y += 2;
}
else location_y++;
year++;
}
location_y %= 7;
//找到M月一号的位置(28不变,29+1,30+2,31+3)
while (month < M) {
if (cal_day(year, month) == 29) location_y += 1;
else if (cal_day(year, month) == 30) location_y += 2;
else if (cal_day(year, month) == 31) location_y += 3;
month++;
//cout << location_y << ' ';
}
location_y %= 7;
4.最后填充二维数组,再输出
//填充二维数组
int this_day = cal_day(year, month);
for (int i = 0; i < this_day; i++) {
arr[location_x][location_y++] = day++;
if (location_y > 6) {
location_y %= 7;
location_x++;
}
}
//输出结果
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (arr[i][j] == 0) {
if (j == 0) cout << " ";
else cout << " ";
}
else
if (j == 0) cout <<right<< setw(3) <<arr[i][j];
else cout << right <<setw(4) <<arr[i][j];
}
cout << endl;
}
四、完整代码
#include<iostream>
#include<iomanip>
using namespace std;
int arr[6][7];
bool leap_year(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true; //是闰年
}
return false;
}
int cal_day(int year,int month) { //计算当月有多少天
int result = 0;
int kk[12] = { 31 ,28,31,30,31,30,31,31,30,31,30,31 }; //bug1:kk初始化已经固定,不会被temp的变化修改
if (leap_year(year) && month == 2) return 29;
else result = kk[month - 1];
return result;
}
int main() {
int Y, M;
cin >> Y >> M;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
arr[i][j] = 0;
}
}
cout << "Sun Mon Tus Wed Thu Fri Sat" << endl;
int location_x = 0,location_y =6, year =1921,month = 1,day =1; //该月天数,1921年一月一号的位置
//找到当年一月一号的位置
while (year < Y) {
if (leap_year(year)) {
location_y += 2;
}
else location_y++;
year++;
}
location_y %= 7;
//找到M月一号的位置(28不变,29+1,30+2,31+3)
while (month < M) {
if (cal_day(year, month) == 29) location_y += 1;
else if (cal_day(year, month) == 30) location_y += 2;
else if (cal_day(year, month) == 31) location_y += 3;
month++;
//cout << location_y << ' ';
}
location_y %= 7;
//cout << location_y << endl;
int this_day = cal_day(year, month);
for (int i = 0; i < this_day; i++) {
arr[location_x][location_y++] = day++;
if (location_y > 6) {
location_y %= 7;
location_x++;
}
}
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (arr[i][j] == 0) {
if (j == 0) cout << " ";
else cout << " ";
}
else
if (j == 0) cout <<right<< setw(3) <<arr[i][j];
else cout << right <<setw(4) <<arr[i][j];
}
cout << endl;
}
return 0;
}
标签:int,31,month,++,location,感觉,year,思路,月历
From: https://blog.csdn.net/2403_87544412/article/details/144944902