题目:http://poj.org/problem?id=3393
AC代码(C++):
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <algorithm>
#include <string.h>
#include <math.h>
#define INF 0x3f3f3f3f
#define eps 1e-8
typedef unsigned long long ULL;
using namespace std;
int monthDays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int ys, ms, ye, me;
bool isLeap(int year) {
if (year < 1582) {
if (year % 4 == 0)return true;
else return false;
}
else if (year >= 1582) {
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0 || year == 1700))return true;
else return false;
}
}
int cal(int year, int month) {
int day = 0;
for (int i = 1; i < year; i++) {
if (isLeap(i))day += 366;
else day += 365;
}
for (int i = 1; i < month; i++) {
if (isLeap(year) && i == 2)day += monthDays[2] + 1;
else day += monthDays[i];
}
if (year > 1752 || (year == 1752 && ms>9))day -= 11;
day++;
return day;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> ys >> ms >> ye >> me;
int goods = 0;
int luckys = 0;
int day = cal(ys, ms);
int first;
int last;
while (1) {
if (ys > ye || (ys == ye&&ms > me))break;
first = (day + 5) % 7;
if (first == 0 || first == 1 || first == 6)goods++;
if (isLeap(ys) && ms == 2)day = day - 1 + monthDays[2] + 1;
else day = day - 1 + monthDays[ms];
if (ys == 1752 && ms == 9)day -= 11;
last = (day + 5) % 7;
if (last == 0 || last == 5 || last == 6)luckys++;
day++;
ms++;
if (ms == 13) {
ms = 1;
ys++;
}
}
cout << luckys << ' ' << goods << endl;
}
//system("pause");
}
总结: 阅读题 + 模拟题. 给定开始和结束的时间, 问你中间有多少个lucky和good的月份. 思路很简单, 计算出这个月的第一天和最后一天是星期几就能判断出来. 若第一天是星期一, 六, 日, 则是good月份, 若最后一天是五, 六, 日, 则是lucky月份. 至于判断某一天是星期几, 可以算出从1年1月1日到那一天总共经过了day天, 那么这一天的星期数就是(day+5)%7. 加5是因为1年1月1日是星期六.