算法设计-模拟日期问题

Posted Mount256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法设计-模拟日期问题相关的知识,希望对你有一定的参考价值。

文章目录

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;

以上是关于算法设计-模拟日期问题的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(C语言版) 栈和队列 算法设计Demo13

C语言 递归算法练习(阶乘,斐波那契..)

C语言模拟FIFO算法,随机生成320条指令,有四块物理块,为啥错了?

模拟算法

C语言第一个C语言小程序 —— 日期算法和万年历

C语言第一个C语言小程序 —— 日期算法和万年历2