试题 算法提高 日期计算
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢400年闰的情况。
输入格式
输入只有一行
YYYY MM DD
输出格式
输出只有一行
W
数据规模和约定
1599 <= YYYY <= 2999
1 <= MM <= 12
1 <= DD <= 31,且确保测试样例中YYYY年MM月DD日是一个合理日期
1 <= W <= 7,分别代表周一到周日
样例输入
2011 11 11
样例输出
5
解题思路:既然2011/11/11是周五,那么2011/11/13就是周日,以后者为 原点,向当前所在日期回溯,计算中间的天数差值,若当前日期>=原点时,差值%7即为当前日期的星期几;若小于原点,(7-差值%7)%7即为当前日期的星期几。不知什么原因只跑了80分,看了一下测试数据,错误的都是2011年之后的日期。。。
代码如下:
#include <iostream>
using namespace std;
struct Date{
int year,month,day;
int dayNo;
int weekNo;
Date(int yy,int mm,int dd):year(yy),month(mm),day(dd){ }
Date(){ }
};
int common[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int ran[12]={31,29,31,30,31,30,31,31,30,31,30,31};
int WNO[7]={7,1,2,3,4,5,6};
bool isRanYear(int YY){
if( (YY%4==0 && YY%100!=0) || YY%400==0 ){
return true;
}
else
return false;
}
int getCurYearDays(Date D){
int daySum=D.day;
if( isRanYear(D.year) ){
for(int i=0;i<D.month-1;i++){
daySum+=ran[i];
}
}
else{
for(int i=0;i<D.month-1;i++){
daySum+=ran[i];
}
}
return daySum;
}
int getCentralDays(int from,int to){
int daySum=0;
for(int i=from;i<to;i++){
if( isRanYear(i) )
daySum+=366;
else
daySum+=365;
}
return daySum;
}
void getWeekNo(Date D){
if(D.year>2011){
int daySum=31+(30-13);//从2011/11/13 周日 开始算
daySum+=getCurYearDays(D);
D.weekNo=WNO[daySum%7];
}
if(D.year==2011){
if(D.month>=11 && D.day>=13){
int daySum=0;
if(D.month==11){
daySum=D.day-13;
D.weekNo=WNO[daySum%7];
}
if(D.month>11){
daySum+=30-13+D.day;
D.weekNo=WNO[daySum%7];
}
}
if(D.month<=11 && D.day<13){
int daySum=0;
if(D.month==11){
daySum+=13-D.day;
D.weekNo=WNO[(7-daySum%7)%7];
}
else{
daySum+=13;
for(int i=D.month;i<11-1;i++){
daySum+=common[i];
}
daySum+=common[D.month-1]-D.day;
D.weekNo=WNO[(7-daySum%7)%7];
}
}
}
if(D.year<2011){
int daySum=0;
daySum+=getCentralDays(D.year+1,2011);
for(int i=0;i<11-1;i++){
daySum+=common[i];
}
daySum+=13;
for(int i=D.month;i<12;i++){
if(isRanYear(D.year))
daySum+=ran[i];
else
daySum+=common[i];
}
if(isRanYear(D.year)){
daySum+=ran[D.month-1]-D.day;
}
else
daySum+=common[D.month-1]-D.day;
D.weekNo=WNO[(7-daySum%7)%7];
}
cout<<D.weekNo<<endl;
}
int main(int argc, char** argv) {
Date DT;
cin>>DT.year>>DT.month>>DT.day;
getWeekNo(DT);
return 0;
}