G
N
I
D
A
O
L

【算法设计-模拟】日期问题

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;
}
posted @ 2023-03-01 10:07  漫舞八月(Mount256)  阅读(25)  评论(0编辑  收藏  举报