AT878 経過日数 题解

Content

输入一个日期,包括三个整数\(y,m,d\),即为这一天是\(y\)年\(m\)月\(d\)日,求出这一天距离\(2014\)年\(5\)月\(17\)日多少天。

数据范围:\(1\leqslant y\leqslant2014,1\leqslant m\leqslant12,1\leqslant d\leqslant31\)。

Solution

P5407的方法有些类似,我的意思是说,核心代码部分,也就是推日期。

P5407这道题目我在去年也写过题解,提到了暴力推日期的代码实现方法,现在我再重新理一遍它的过程:

  • 一开始,设定起始日期和目标日期。

注意,这里和P5407的不同点是,P5407一定是顺向推日期的(一年的元旦比母亲节还晚就不科学了),但是这一题中,输入的日期就可能比2014年5月17日早(比如2014年12月31日),所以,你可以像我后面讲的方法一样,逆向推日期(其实也不难),要么也可以将起始日期的三个元素和目标日期的三个元素(三个元素无需多提)逐一对应调换,然后再顺向推日期亦可。

  • 然后判断,如果起始日期比目标日期晚,设有个变量\(flag\)初始值为\(1\),用来判断上述条件,此时\(flag\)变成\(-1\)。比较方法跟\(\texttt{sort}\)中多关键字的比较函数的写法有些类似。否则\(flag\)保持为\(1\)不变。

开始愉快地推日期。(注意先后顺序不能调换!

  • 先判断是否和目标日期相等,如果相等直接结束推日期。

  • 如果\(flag\)为\(-1\),每次天数减\(1\)。然后判断如果天数\(<1\),那么月数减\(1\),天数变为这个月的最大天数。再判断此时如果月份数也\(<1\),那么年数也减\(1\),月数和天数分别变成\(12\)和\(31\)。

  • 否则,如果\(flag\)为\(1\),每次天数加\(1\)。然后判断如果天数\(>\)当前所在月的最大天数,那么月数加\(1\),天数归\(1\),再判断此时如果月份数\(>12\),那么年数也加\(1\),月数和天数都归1。

在推日期的过程中,引进一个\(cnt\)变量记录天数,每次操作过后\(cnt\)加\(1\),推完日期之后\(cnt\)即为本题的答案,输出(不要忘了输出完后面换行!这是AT题库最致命的一个坑!)。

另外一种,就是调换日期再顺着推的方法,请读者自己思考,本题解不做过多解释。

Code

#include <cstdio>
#include <algorithm>
using namespace std;

int y, m, d, yy = 2014, mm = 5, dd = 17, flag = 1, cnt;
int ddd[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

inline int judge(int x) {
	if(!(x % 100)) {
		if(x % 400)	return 0;
		return 1;
	}
	if(x % 4)	return 0;
	return 1;
}

int main() {
	scanf("%d%d%d", &y, &m, &d);
	if(y != 2014 && y > 2014)	flag = -1;
	else if(m != 5 && m > 5)	flag = -1;
	else if(d != 17 && d > 17)	flag = -1;
	if(flag == -1)	swap(y, yy), swap(m, mm), swap(d, dd);
//	printf("%d %d %d %d %d %d", y, m, d, yy, mm, dd);
	while(1) {
//		printf("Today is %d.%d.%d\n", y, m, d);
		if(d == dd && m == mm && y == yy) break;
		cnt++;
		if(flag == -1) {
			d--;
			if(d < 1) {m--; d = ddd[m] + (judge(y) && m == 2 ? 1 : 0);}
			if(m < 1) {y--; m = 12; d = 31;}
		} else {
			d++;
			if(d > ddd[m] + (judge(y) && m == 2 ? 1 : 0)) {m++; d = 1;} 
			if(m > 12) {y++; m = 1;}
		}
	}
	printf("%d\n", cnt);
	return 0;
}
上一篇:微信开发中fakeid与openid的区别


下一篇:微信订阅号,获取用户openid