九度OJ 1096 日期差值
来源:互联网 发布:淘宝店怎么看分 编辑:程序博客网 时间:2024/04/29 22:31
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
原题地址:http://ac.jobdu.com/problem.php?pid=1096
题目描述:
- 输入:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
- 输出:
每组数据输出一行,即日期差值
- 样例输入:
2011041220110422
- 样例输出:
11
- 来源:
2009年上海交通大学计算机研究生机试真题
之前没有接触过和日期有关的问题,第一次接触觉得还是比较有技巧的。
这道题考察的是日期类问题里最基本的问题——求两个给定日期间的天数差。第一反应就是判断一下这两个日期间有多少闰年、多少月份之类的办法,但是显然实现起来并不容易而且很可能出错,需要有一个统一的策略,书上提到“解决这类区间问题有一个统一的思想——把原区间问题统一到起点确定的区间问题上去”,因此提出了一种把特定日期间的天数差,统一到这两个日期与一个原点时间(如0000年1月1日)的天数差,即X1-X2转换成了(X1-X0) - (X2-X0),当然必要时还要加绝对值,以及区间开闭是否加1。
通过这样做还有个好处就是利用了预处理,在程序真正测试输入数据之前,预处理出范围内每个日期与原点的天数差并保存在数组中,之后的每组测试数据就只需要O(1)复杂度,将这两个时间的偏移读出来作差、取绝对值。预处理是空间换时间的重要手段(“保存预处理所得到数据所需的内存来换取实时处理所需要的耗时”)。
值得注意的几个点:
- 闰年的判断规则:当年数能被4整除但不能被100整除时为闰年(如1900年为平年),或者年数能被400整除。定义宏表达式判断非常简洁明了。
- 计算某个日期与原点日期的差的做法如下:定义一个类DATE,不仅起到表示日期的作用,还能自动计算出下一天的具体日期(涉及月份间、年份间的递进),一方面不断计算出当前日期的下一个日期,另一方面累加计数器,计算当前日期与原点日期的偏移。
- 使用三维数组的下标表示年、月、日,即将日期本身与存储地址联系起来,提供了很方便的索引(有点Hash的感觉)
- 在%和d之间插入数字来读取特定位数的技巧:输入时用%4d来读取八位数的前四位年份,%2d%2d来读取月和日,比手动取字符串子串方便多了:)
- 耗费大量内存的数组或变量应定义在全局中,否则函数的栈空间将不足以提供大量内存空间,导致栈溢出StackOverflow,当然malloc也是可以的
这类题目的变题可以有很多,比如给定日期在那一年中是第几天,某个日期是星期几(九度OJ 1043 Day of Week)等等,思路都是一样滴。AC代码如下:#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>using namespace std;#define MAX_YEAR 5001#define IsLeapYear(x) ((x%100!=0 && x%4==0)||x%400==0)?1:0 //判断x年是不是闰年int dayOfMonth[13][2] = //每个月的在平闰年的表现{ 0,0, //无意义 31,31, 28,29, //二月的平闰天数不同 31,31, 30,30, 31,31, 30,30, 31,31, 31,31, 30,30, 31,31, 30,30, 31,31};typedef struct date //定义日期结构体,用于之后的预处理{ int year,month,day; void next_day() //当前日期的下一天 { day++; if(day > dayOfMonth[month][IsLeapYear(year)]) //超过了当年当月的最大天数 { day = 1; month++; if(month > 12) //一年过完 { month = 1; year++; } } }}DATE;int buf[MAX_YEAR][13][32]; //存放MAX_YEAR年中的所有日期与基准日期0000年1月1日的间隔void PreProcess() //采用预处理,用空间换时间,提前处理好,读取时只用O(1)复杂度{ DATE tmp; tmp.year = 0; tmp.month = 1; tmp.day = 1; int interval = 0; //记录每个日期与基准日期的日期差 while(tmp.year != MAX_YEAR) { buf[tmp.year][tmp.month][tmp.day] = interval; tmp.next_day(); ++interval; } return;}int main(){ PreProcess(); int y1, m1, d1; int y2, m2, d2; while(~scanf("%4d%2d%2d", &y1, &m1, &d1)) //注意scanf里%d中的数字表示截取多少位,实现了直接分解为三个int { scanf("%4d%2d%2d", &y2, &m2, &d2); cout << abs(buf[y1][m1][d1]-buf[y2][m2][d2])+1 << endl; //注意绝对值和+1 } return 0;}
内存占用:9644Kb 耗时:30ms(预处理的效果明显?)算法复杂度:取决预处理计算日期的复杂度:O(n)
0 0
- 九度OJ 1096 :日期差值
- 九度OJ 1096 日期差值
- 九度OJ 题目1096:日期差值
- 九度oj-1096-日期差值
- 九度 oj 题目1096:日期差值
- 九度OJ-1096:日期差值
- 九度 OJ 题目1096:日期差值
- 九度OJ 1096 日期差值
- 九度OJ 1096 日期差值
- 九度OJ 1096:日期差值 (日期计算)
- 九度OJ 1096 日期差值(经典)
- 九度OJ 1096 日期差值(经典)
- 【王道九度OJ】1061日期差值
- 九度1096 日期差值
- 九度1096:日期差值
- 九度题目1096:日期差值
- [九度]题目1096:日期差值
- 九度题目1096:日期差值
- 影响数据库性能的几个方面--服务器硬件
- 安装package control
- 南京Oj1225,石子合并,DP
- Python编写打飞机小游戏
- (集合)HashMapDemo3
- 九度OJ 1096 日期差值
- Java的四种内部类
- android 闪屏页的倒计时和发送验证码的倒计时控件
- Spring基础知识汇总
- Hibernate配置Oracle自增项目
- ASCIISTR,ASCII,CHR函数的区别
- RAM、ROM、内存还有硬盘,它们到底有什么区别
- gulp中文api
- 文件的创建、删除、重命名