1. 程式人生 > >2017百度之星資格賽(A)1005 今夕何夕(日期計算)

2017百度之星資格賽(A)1005 今夕何夕(日期計算)

題目中文,不再詳述題意

思路:簡單的日期計算,基礎題。自己這個寫法分類討論多一些,細節多,偏於繁瑣,容易出錯,聽人討論說,有比較簡潔的演算法,感興趣的小夥伴可以上網搜一搜。

// 今夕何夕.cpp 執行/限制:15ms/1000ms
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int month[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 judge(int y) {//判斷瑞年
	if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
		return 1;
	}
	return 0;
}
int calPre(int flag, int m, int d) {//flag用於說明瑞年平年,m-d為日期,計算本年該日期前的天數(包括本天)
	int re = 0;
	for (int i = 1; i < m; i++) {
		re += month[flag][i];
	}
	re += d;
	return re;
}
int calBack(int flag, int pre) {//計算本年該日期後的天數(不包括本天)
	if (flag) {
		return 366 - pre;
	}
	else {
		return 365 - pre;
	}
}
int main(){
	int t;
	int y, m, d;
	scanf("%d", &t);
	while (t--) {
		scanf("%d-%d-%d", &y, &m, &d);
		int flag = judge(y);//標記給出日期的瑞年平年
		int pre = calPre(flag, m, d);
		int back = calBack(flag, pre);
		int re = back, i;
		if (m == 1) {//一月份
			for (i = y + 1;; i++) {
				re += pre;
				if (re % 7 == 0) {
					break;
				}
				int f = judge(i);
				re += f ? 366 - pre : 365 - pre;
			}
		}
		else if(m > 2){//二月後
			for (i = y + 1;; i++) {
				int f = judge(i);
				int p = flag > f ? pre - 1 : (f > flag?pre + 1 : pre);
				re += p;
				if (re % 7 == 0) {
					break;
				}
				re += f ? 366 - p : 365 - p;
			}
		}
		//二月;二月是個特殊月份,所以對月份分類討論;
		//二月份又得分類討論日子是不是29號,因為二月由於年數不同可能天數不同,存在開始時間為29號,當前年沒有29號的情況
		else if(d == 29){//日期為02-29
			for (i = y + 1;; i++) {
				int f = judge(i);
				if (!f) {//該年沒29號
					re += 365;
					continue;
				}
				re += pre;
				if (re % 7 == 0) {
					break;
				}
				re += 366 - pre;
			}
		}
		else {
			for (i = y + 1;; i++) {
				re += pre;
				if (re % 7 == 0) {
					break;
				}
				int f = judge(i);
				re += f?366 - pre:365 - pre;
			}
		}
		printf("%04d\n", i);
	}
    return 0;
}