这篇文章将介绍常见的日期处理与进制转换问题。
1.日期处理
以题目为例:http://codeup.hustoj.com/problem.php?cid=100000578&pid=0
问题 A: 日期差值
题目描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。
输入
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出
每组数据输出一行,即日期差值
样例输入
1 | 20130101 |
样例输出
1 | 5 |
细节
我们需要处理平年和闰年,大月和小月的问题。
思路
我们不妨设第一个日期是早于第二个日期的(如果不是就交换顺序)。
求日期差值的问题很直接的一个思路就是让第一个日期不断加1天,直到和第二个日期相等为止。
为了存放平年和闰年每个月的天数,我们建立一个二维数组int month[13][2]
,第一维存放月份,从1到12,第0位不用,第二维为0表示平年,为1表示闰年。
我们可以先让第一个日期的年份加到与第二个日期的年份相差1为止,这样可以加快速度。对于其中的年份,只要根据平年还是闰年加365或366天即可。之后再不断让天数加1就行。
代码
1 |
|
优化代码参考:https://blog.csdn.net/numb123r/article/details/112722689
优化代码经过测试,存在漏洞,“20200229;20220301”这组数据会少一天,好像从闰年开始日期<=2月都会少一天。
CODEUP的数据应该不完整,上面这组数据和优化前代码答案不一样,但都能过。
把25行代码解注释应该就是正确答案,但是AC不了(疑惑)。
直接硬算是最靠谱的,不需要对年数优化。
这题一般写法还是比较简单,但是优化时WA好几发,注意写法。
2.进制转换
以题目为例:
https://pintia.cn/problem-sets/994805260223102976/problems/994805299301433344
1022 D进制的A+B (20 分)
输入两个非负 10 进制整数 A 和 B (≤2^30−1),输出 A+B 的 D (1<D≤10)进制数。
输入格式:
输入在一行中依次给出 3 个整数 A、B 和 D。
输出格式:
输出 A+B 的 D 进制数。
输入样例:
1 | 123 456 8 |
输出样例:
1 | 1103 |
思路
将一个P进制数转换为Q进制数,分两步:
- 将P进制数x转换为10进制数y:
1 | int y = 0,product = 1; |
搞不清楚的话,可以拿二进制数转换为十进制数作为参考。
- 将10进制数y转换为Q进制数z:
除基取余法。
1 | int z[40],num = 0; // 数组z用于存放Q进制数y的每一位,num为位数 |
最后将数组z从高位z[num-1]到低位z[0]输出,就是Q进制数z。
搞不清楚的话,可以拿十进制数转换为二进制数作为参考。
代码
1 |
|
提一点,PAT的编译器,如果按照scanf
的一般写法可能会警告,将scanf("%d",&t);
改成if(scanf("%d",&t)){};
就不会警告了。