上海交大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;
}

猜你喜欢

转载自blog.csdn.net/WX_1218639030/article/details/83863405