日期问题的求解大致分为以下几种类型:
1、找寻天数和年月日之间的对应关系
2、已知某天为周几,求过了n天后是星期几
3、已知某天年月日求出过了n天后的年月日。
这类问题的统一解题思路是:已知某天的年月日,求下一天的年月日。
关注:每个月份有多少天?
1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | |
天数 | 31 | 28、29 | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 |
月份的对应关系可以使用数组存储起来。
对于2月份,我们需要根据是否闰年来更改天数。
注:以下代码均通过了牛客网代码测试,请安心食用。
题目一:设计一个程序能计算一个日期加上若干天后是什么日期
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool is_leapYear(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))return true;
return false;
}
void printDate(int year, int month, int day, int n) {
int monthOfDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (is_leapYear(year))monthOfDay[2] = 29;
else monthOfDay[2] = 28;
while (n > 0) {
while (day <= monthOfDay[month] && n > 0) {
day++;
n--;
}
if (n == 0)break;
month++;
day = 1;
if (month > 12) {
month = 1;
year++;
if (is_leapYear(year))monthOfDay[2] = 29;
else monthOfDay[2] = 28;
}
}
printf("%d-", year);
if (month < 10)printf("0%d-", month);
else printf("%d-", month);
if (day < 10)printf("0%d\n", day);
else printf("%d\n", day);
}
int main() {
int m;
int year, month, day, n;
scanf("%d", &m);
while (m > 0) {
scanf("%d%d%d", &year, &month, &day);//输入已知年月日
scanf("%d", &n);//求取过了n天之后的年月日
printDate(year, month, day, n);
m--;
}
return 0;
}
题目二:编写一个日期类,要求按xxxx-xx-xx 的格式输出日期,实现加一天的操作
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool is_leapYear(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))return true;
return false;
}
void nextDay(int year, int month, int day) {
int monthOfDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (is_leapYear(year))monthOfDay[2] = 29;
else monthOfDay[2] = 28;
day++;
if (day > monthOfDay[month]) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
printf("%d-", year);
if (month < 10)printf("0%d-", month);
else printf("%d-", month);
if (day < 10)printf("0%d\n", day);
else printf("%d\n", day);
}
int main() {
int m;
scanf("%d", &m);
int year, month, day;
while (m > 0) {
scanf("%d%d%d", &year, &month, &day);
nextDay(year, month, day);
m--;
}
return 0;
}
题目三:给出年分m和一年中的第n天,算出第n天是几月几号
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool is_leapYear(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))return true;
return false;
}
void printDate(int year, int n);
int main() {
int n, year;
while (scanf("%d%d", &year, &n) != EOF) {
printDate(year, n);
}
return 0;
}
void printDate(int year, int n) {
int monthOfDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int month = 1;
int day = 0;
if (is_leapYear(year))monthOfDay[2] = 29;
else monthOfDay[2] = 28;
while (n > 0) {
while (n > monthOfDay[month]) {
n = n - monthOfDay[month];
month++;
}
day++;
n--;
}
printf("%d-", year);
if (month < 10)printf("0%d-", month);
else printf("%d-", month);
if (day < 10)printf("0%d\n", day);
else printf("%d\n", day);
}
题目四:有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool is_leapYear(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))return true;
return false;
}
int main() {
int date1, date2;
scanf("%d%d", &date1, &date2);
if (date1 > date2) {
int tmp = date1;
date1 = date2;
date2 = tmp;
}
int year1, year2, month1, month2, day1, day2;
year1 = date1 / 10000;
date1 = date1 % 10000;
year2 = date2 / 10000;
date2 = date2 % 10000;
month1 = date1 / 100;
date1 = date1 % 100;
month2 = date2 / 100;
date2 = date2 % 100;
day1 = date1;
day2 = date2;
int monthOfDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int sum = 0;
if (year1 != year2 || month1 != month2 || day1 != day2) {
if (day2 < day1) {
if (month2 != 1) {
day2 = day2 + monthOfDay[month2];
} else {
year2--;
month2 = 12;
day2 = day2 + 31;
}
}
sum = sum + day2 - day1;
if (month2 < month1) {
year2--;
month2 = 12 + month2;
}
for (int i = month1; i < month2; i++) {
if (i > 12)sum = sum + monthOfDay[i - 12];
else sum = sum + monthOfDay[i];
}
if (year2 > year1) {
for (int i = year1; i < year2; i++) {
if (is_leapYear(i))sum = sum + 366;
else sum = sum + 365;
}
}
}
sum++;
printf("%d\n", sum);
return 0;
}
题目五:输入年月日,计算该填是本年的第几天。例如1990 年9 月20 日是1990 年的第263 天,2000 年5 月1 日是2000 年第122 天。
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool is_leapYear(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))return true;
return false;
}
void printDays(int year, int month, int day);
int main() {
int n;
scanf("%d", &n);
int* year = (int*)malloc(n * sizeof(int));
int* month = (int*)malloc(n * sizeof(int));
int* day = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &year[i], &month[i], &day[i]);
}
for (int i = 0; i < n; i++) {
printDays(year[i], month[i], day[i]);
}
return 0;
}
void printDays(int year, int month, int day) {
int monthOfDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (is_leapYear(year))monthOfDay[2] = 29;
else monthOfDay[2] = 28;
int sum = 0;
for (int i = 1; i < month; i++) {
sum += monthOfDay[i];
}
sum += day;
printf("%d\n", sum);
}
补充
在编写多道题目后,才发现有一种更加简单灵活的方式可以输出自己想要的格式。
上面在输出日期时因为不知道日期是不是只有个位数而做了判断。但实际上,c语言的printf可以通过编辑输出格式实现这一点。
int a=5;
printf("%02d\n",a);//输出结果:05
上面这段代码中,2表示宽度,0代表如果这个输出不足2位,那就用0来补齐。
个人认为这种方法比之前我的那种聪明多了。