UVA602 日期計算(2)+模擬+細節

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章