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;
}