1. 程式人生 > >上海交大OJ 1008. 二哥買期貨

上海交大OJ 1008. 二哥買期貨

emmm....我的程式碼過不了OJ時間超時 只能得80分

-----------------------------------------------------------------------

Description

二哥想知道在一段時期內,一共有多少個交易日。期貨交易日的限定如下:

  1. 週六、週日不能交易
  2. 元旦期間(1月1日)不能交易
  3. 五一勞動節期間(5月1日至3日)不能交易
  4. 十一國慶節期間(10月1日至7日)不能交易
  5. 沒有在上述要求中提到的日期均可交易

Input Format

第一行有一個整數n,表示一共有n組資料。

每組資料都有一行,是兩個用空格分開的日期,分別為開始日期和結束日期。日期格式為YYYY-MM-DD(比如2010-11-11);資料保證開始日期不晚於結束日期。

對於所有資料:n≤365 n≤365

對於30%的資料:日期範圍從2010-11-23至2012-12-21

對於70%的資料:日期範圍從1900-01-01至9999-12-31

Output Format

輸出共n行,每行一個整數,對應於一組資料。

每組資料需要輸出在指定日期區間內,共有多少個交易日;區間的開始和結束日期也算在內(如果是交易日的話)。

Sample Input

4
2010-11-18 2010-11-20
2010-01-01 2010-01-01
2010-05-01 2010-05-03
2010-10-01 2010-10-07

Sample Output

2
0
0
0

用於計算是否為週末的方法基姆拉爾森 公式

//基姆拉爾森公式
//是週末返回 true 否返回false
bool liuri(int y,int m,int d){

    if(m == 1 || m == 2) //把一月和二月換算成上一年的十三月和是四月
    {
        m += 12;
        y--;
    }

     int Week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;

     //0-6 代表著星期一到週日
     if(Week == 5 || Week == 6)
        return true;
    //週末返回true 非週末返回false
     else return false;
}

計算是否為閏年

//判斷是否閏年
//是 返回 1 否 返回 0
int judge(int Y){
    //當Y是4的倍數且Y不是100的倍數 或者 Y是400的倍數
    if((Y % 4 == 0 && Y % 100 != 0) || (Y % 400 == 0))
        return 1;

    else return 0;
}

總體程式碼

#include <cstdio>

using namespace std;

struct Node
{
    int Year;
    int Month;
    int Day;
}e[365][2];

//judge[0] 非閏年
//judge[1] 閏年
int judgeY[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
};

//判斷是否閏年
//是 返回 1 否 返回 0
int judge(int Y){
    //當Y是4的倍數且Y不是100的倍數 或者 Y是400的倍數
    if((Y % 4 == 0 && Y % 100 != 0) || (Y % 400 == 0))
        return 1;

    else return 0;
}

//基姆拉爾森公式
//是週末返回 true 否返回false
bool liuri(int y,int m,int d){

    if(m == 1 || m == 2) //把一月和二月換算成上一年的十三月和是四月
    {
        m += 12;
        y--;
    }

     int Week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;

     //0-6 代表著星期一到週日
     if(Week == 5 || Week == 6)
        return true;
    //週末返回true 非週末返回false
     else return false;
}

//判斷是否放假 false - 不放 true - 放
bool fan(int y,int m,int d){

    //返回p = true則是週末
    bool p = liuri(y,m,d);

    //滿足任意放假條件則返回true 否則返回 false
    //週末 元旦 五一三天 國慶
    if(p == true || (m == 1 && d == 1) || (m == 5 && d <= 3) || (m == 10 && d <= 7))
        return true;
    else return false;

}

//獲取請假時間
int getAnswer(int u){

    //sum 記錄工作日天數
    int sum = 0;

    //jy 代表是否為閏年
    int jy = judge(e[u][0].Year);

    //迴圈累加
    while (e[u][0].Year != e[u][1].Year || e[u][0].Month != e[u][1].Month || e[u][0].Day != e[u][1].Day) {

        //當判斷返回這一天不是 節假日時sum++
        if(fan(e[u][0].Year,e[u][0].Month,e[u][0].Day) == false)
            sum++;

        //天數+1
        e[u][0].Day++;

        //判斷是否應該進入下一個月
        if(e[u][0].Day == judgeY[jy][e[u][0].Month] + 1){

            //是 - month + 1
            //day 重新回到1號
            e[u][0].Month++;
            e[u][0].Day = 1;
        }

        //判斷是否應該進入下一年
        if(e[u][0].Month == 13){

            //是 - year + 1
            //month 重新回到一月
            e[u][0].Year++;
            e[u][0].Month = 1;

            //重新判斷新的一年是否為閏年
            jy = judge(e[u][0].Year);
        }
    }

    //最後一天 判斷(防漏)
    if(fan(e[u][0].Year,e[u][0].Month,e[u][0].Day) == false)
        sum++;

    return sum;
}

int main(int argc, char const *argv[]) {
    //N行
    int N;

    scanf("%d",&N);

    //輸入起始 終止年月日
    for(int i = 0;i < N;i++){
        for(int j = 0;j < 2;j++){
            //getchar() 去除 ‘-’
            scanf("%d",&e[i][j].Year);
            getchar();
            scanf("%d",&e[i][j].Month);
            getchar();
            scanf("%d",&e[i][j].Day);
        }
    }

    //多組資料
    for(int i = 0;i < N;i++){
        printf("%d\n",getAnswer(i) );
    }
    
    return 0;
}