【算法设计-模拟】日期问题
1. 几月几号是一年中的第几天?
输入:
年 月 日
输出:
该天是在该年中的第几天
输入和输出样例:
2000 1 31
31
2000 6 28
180
1990 5 20
140
代码:
#include <stdio.h>
int monthDay[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int main(){
int year, month, day;
while (scanf("%d %d %d", &year, &month, &day) != EOF){
int result, i;
for (i = 1, result = day; i < month; i++){
// 能被400整除,或者能被4整除但不能被100整除的都是闰年
bool reap = (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
result += monthDay[reap][i];
}
printf("%d\n", result);
}
return 0;
}
2. 一年中的第几天是几月几号?
输入:
年 第n天
输出:
年 月 日
输入和输出样例:
2000 360
2000-12-25
2000 365
2000-12-30
2000 366
2000-12-31
2001 365
2001-12-31
2001 344
2001-12-10
2000 36
2000-02-05
代码:
#include <stdio.h>
int monthDay[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int main(){
int year, num;
while (scanf("%d %d", &year, &num) != EOF){
int month, day;
int i, result;
// 能被400整除,或者能被4整除但不能被100整除的都是闰年
bool reap = (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
for (i = 1, result = num; result > monthDay[reap][i]; i++) // 天数累计相减
result -= monthDay[reap][i];
month = i;
day = result;
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
3. 给定日期,求加上x天后的日期
输入:
年 月 日 第x天
输出:
年 月 日
输入和输出样例:
2008 2 3 100
2008-05-13
2023 1 1 31
2023-02-01
2023 1 12 107
2023-04-29
2023 1 12 384
2024-01-31
2023 1 12 453
2024-04-09
2023 1 12 719
2024-12-31
2023 1 12 730
2025-01-11
代码:
#include <stdio.h>
int monthDay[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int main(){
int year, month, day, num;
while (scanf("%d %d %d %d", &year, &month, &day, &num) != EOF){
bool reap = (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
int result, i;
// 输入的年月日转化为该年的第几天
for (i = 1, result = day; i < month; i++)
result += monthDay[reap][i];
num += result; // 加上输入的天数
// 求第几天是几年几月几号
for (i = 1; num > monthDay[reap][i]; ){
num -= monthDay[reap][i]; // 累计相减
i++; // 月份加1
if (i > 12){ // 若月份超过12
year++;
i = 1;
reap = (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
}
// 月份先加1,再判断月份有无溢出,处理完溢出事件后,最后才判断 累计相减的天数 是否小于 一个月的天数
// 因此不能把 i++ 写入 for 语句中
}
month = i;
day = num;
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
4. 两个日期相差了多少天?
输入:
年 月 日
年 月 日
输出:
相差了x天
输入和输出样例:
2021 1 2
2019 4 26
617
2021 7 17
2021 3 7
132
2021 12 31
2021 1 1
364
2022 6 9
2020 11 6
580
2023 2 28
2023 3 1
1
代码:
#include <stdio.h>
#include <math.h>
int monthDay[2][14] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 365},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 366}
};
typedef struct{
int year;
int month;
int day;
int numsDay; // 一年中的第几天
bool reap; // 是否为闰年
} Date;
// 能被400整除,或者能被4整除但不能被100整除的都是闰年
bool isReap (int year){
return (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
}
// 年月日转化为该年的第几天
int numsDayFun (Date d){
int i, result;
for (i = 1, result = d.day; i < d.month; i++)
result += monthDay[d.reap][i];
return result;
}
int main(){
Date date1, date2;
while (scanf("%d %d %d %d %d %d", &date1.year, &date1.month, &date1.day, &date2.year, &date2.month, &date2.day) != EOF){
int result = 0;
date1.reap = isReap(date1.year);
date2.reap = isReap(date2.year);
date1.numsDay = numsDayFun(date1); // 将日期转化为该年的第几天,这样就仅需关注年份和该年中的第几天这两个数据
date2.numsDay = numsDayFun(date2);
//printf("%d %d\n", date1.numsDay, date2.numsDay);
if (date1.year < date2.year){ // 如果两者年份不同(date1年份小于date2年份)
result = monthDay[date1.reap][13] - date1.numsDay; // 先加上 date1 该年的剩余天数
for (int i = date1.year + 1; i < date2.year; i++) // 再加上 date1 ~ date2 之间的天数
result += monthDay[isReap(i)][13];
result += date2.numsDay; // 最后加上 date2 的天数
}
else if (date1.year > date2.year){
result = monthDay[date2.reap][13] - date2.numsDay;
for (int i = date2.year + 1; i < date1.year; i++)
result += monthDay[isReap(i)][13];
result += date1.numsDay;
}
else{ // 如果两者年份相同,直接相减即可
result += abs(date1.numsDay - date2.numsDay);
}
printf("%d\n", result);
}
return 0;
}
5. 给定一个日期的星期,求另一个日期是星期几
输入:
年 月 日 星期几
年 月 日
输出:
星期几
输入和输出样例:
2023 3 1 3
2022 12 10
6
2023 3 1 3
2023 4 5
3
2023 3 1 3
2024 6 7
5
2023 3 1 3
2022 7 11
1
2023 3 1 3
2021 9 11
6
2023 3 1 3
2017 10 15
0
代码:
#include <stdio.h>
int monthDay[2][14] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 365},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 366}
};
typedef struct{
int year;
int month;
int day;
int week; // 星期几,0表示星期天,1~6表示星期一到星期六
int numsDay; // 一年中的第几天
bool reap; // 是否为闰年
} Date;
// 能被400整除,或者能被4整除但不能被100整除的都是闰年
bool isReap (int year){
return (year % 100 != 0) && (year % 4 == 0) || (year % 400 == 0);
}
// 年月日转化为该年的第几天
int numsDayFun (Date d){
int i, result;
for (i = 1, result = d.day; i < d.month; i++)
result += monthDay[d.reap][i];
return result;
}
int main(){
Date date1, date2;
while (scanf("%d %d %d %d %d %d %d", &date1.year, &date1.month, &date1.day, &date1.week, &date2.year, &date2.month, &date2.day) != EOF){
int result = 0;
date1.reap = isReap(date1.year);
date2.reap = isReap(date2.year);
date1.numsDay = numsDayFun(date1); // 将日期转化为该年的第几天,这样就仅需关注年份和该年中的第几天这两个数据
date2.numsDay = numsDayFun(date2);
//printf("%d %d\n", date1.numsDay, date2.numsDay);
if (date1.year < date2.year){ // 如果两者年份不同(date2年份大于date1年份,则结果为正)
result = monthDay[date1.reap][13] - date1.numsDay; // 先加上 date1 该年的剩余天数
for (int i = date1.year + 1; i < date2.year; i++) // 再加上 date1 ~ date2 之间的天数
result += monthDay[isReap(i)][13];
result += date2.numsDay; // 最后加上 date2 的天数
}
else if (date1.year > date2.year){ // 如果两者年份不同(date2年份小于date1年份,则结果为负)
result = monthDay[date2.reap][13] - date2.numsDay;
for (int i = date2.year + 1; i < date1.year; i++)
result += monthDay[isReap(i)][13];
result += date1.numsDay;
result = -result; // 因为date2年份小于date1年份,所以结果需要加负号
}
else{ // 如果两者年份相同,则date2-date1
result += date2.numsDay - date1.numsDay;
}
if (result > 0) // 如果date2 > date1
date2.week = (date1.week + result % 7) % 7;
else // 如果date2 < date1
date2.week = (date1.week + result % 7 + 7) % 7; // 注意这里的 result % 7 是负数
printf("%d\n", date2.week);
}
return 0;
}