1 题意
两种日历计算对应的日期的星期几?
刚开始理解错题意了,不是说以1752年9.2与1752.9.14作为分界线,计算天数时,查询日期在分界线前的天数计算用旧历闰年规则计算;查询日期在后面的、日期就分成两半,界线前的按旧历、界线后的按新历闰年规则计算,不是这样的。如果这样那么新历的延后几天用来弥补之前的误差就没有了意义,而是说:
查询日期在1752.9.2之前的,计算天数用旧历的计算闰年的规则;查询日期在1752.9.14之后的,计算天数直接全用新历的计算闰年的规则,这样题目中说的弥补误差才是有意义的。也就是说,本质上,问题是两种日历计算对应的日期的星期几。
2分析
有很多坑。上面的题意算一个。
其次,检查无效日期,分两类,一类是错误的即比如1月“89日”2013年的这种,而对应不同月份,比如1月和2月,上限分别是31天和30天,而对于是否闰年的2月,也同样有不一样的上限;其次,另一类是对应题意的无效日期,即1752.9.3~1752.9.13是不存在的,是新历和旧历都不存在的,旧历按照Sample Output,是从最初(公元1年)到1752.9.2,而新历是从1752.9.14到现在或者未来。
而计算星期几,网上有这样的计算公式。这里没有用公式,是用的从公元1年1月1日(包括这一天)到所查日期(包括所查日期)一共多少天,week[day%7]就是周几,而week数组是从0开始的,week[0]对应周日,week[1]对应周一......week[6]对应周六。但要注意,这样的计算方式是用新历来算(因为旧历有误差),这样算出的对于1752.9.2之前的数算出的周几再和Sample Output给出的对应日期的周几相比较(题目中可用的是,2 11 1732、9 2 1752),从而得出新历和旧历转换的规律,old_week=(new_week+5)%7。
因为细节比较多,所以代码个部分实现的顺序也要注意,不然因为之前各个变量有初始化的原因,可能计算出错误的结果。
3学习
1
凡是与日期转换有关,应学习关于闰年的处理方式,单独一个函数判断闰年( int run_year() )&&二维数组来存储有关闰年的天数选择:
int year_day[2]={365,366};
int month_day[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};
2
计算天数:是从公元1年1月1日到查询日期(包括在内)有多少天,day%7即周几,而week数组是从0到6分别对应周天、周一......周六,当然对应其他的日期开始也可以只要知道开始日期对应的周几,此方法仅对于新历有效(闰年计算规则:被4整除但不被100整除的,以及被400整除的)。
4
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
int year_day[2]={365,366};
int month_day[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};
char month_name[][20]={"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
char week_name[][20]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int sum,year,month,day,week;
int old;
int run_year(int temp){ ///Note!!! 根据题意,历史原因,前后的闰年定义不一样!!!
if(!old){ //history,
//return (temp%4 == 0) ? true : false;
if(temp%4==0) return 1;
else return 0;
}
else{ //new,
//return (temp%100 == 0)?(temp%400 == 0?true:false):(temp%4 == 0?true : false);
if( ( temp%4==0&&temp%100!=0 )|| (temp%400==0) ) return 1;
else return 0;
}
}
int Judge(){
if(year<1) return 0;
if(month<1||month>12) return 0;
if(day<1) return 0;///Note!!! fenlei
if(day>month_day[run_year(year)][month]) return 0;
if(year==1752&&month==9&&(2<day&&day<14)) return 0; ///Note!!!
return 1;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d%d",&month,&day,&year)){
if(month==0&&day==0&&year==0) break;
old=0;
sum=0;
if(year>1752||(year==1752&&month>9)||(year==1752&&month==9&&day>2)){///Note!!! if(year>=1752&&month>=9&&day>=2)
old=1;
}
if(Judge()==0){
printf("%d/%d/%d is an invalid date.\n",month,day,year);
continue;
}
for(int i=1;i<year;i++){//历史上,从公元1年开始的,没有公元0年
sum+=year_day[run_year(i)];
}
for(int i=1;i<month;i++){
sum+=month_day[run_year(year)][i];
}
sum+=day;
week=sum%7;
if(!old){ //new,
week=(week+5)%7;
}
//cout<<old<<endl;
//cout<<sum<<endl;
//cout<<week<<endl;
printf("%s %d, %d is a %s\n",month_name[month],day,year,week_name[week]);
}
return 0;
}