交大oj-1008-二哥买期货 C++ 总结

交大oj-1008-二哥买期货 C++ 总结


1,基姆拉尔森计算公式

这个公式可以根据日期计算这一天是星期几,具体公式如下:
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7

  • y:Year 年
  • m:Month 月
  • d:Day 天
  • W:Week 转换后的星期

    需要注意的是,要把一月与二月看成是上一年的十三月与十四月。C++代码如下:

//这个函数返回的结果是0-6的整数,表示星期一到星期天
int getWeekNumber(int year, int month, int day)
{
    if (month == 1 || month == 2) {
        year--;
        month += 12;
    }
    return ((day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7);
}

2,这道题的总体的思路?

现在这道题还没有AC,总体思路待写完后再补充。

3,已经AC的代码 C++

#include <iostream>
#include <stdio.h>
using namespace std;
int dayOfMonth[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,2月作为上一年的13,14月份
struct Date
{
    int y, m, d;
    int leap()
    {
        return (y % 4 == 0 && y % 100 != 0 || y % 400 == 0 ? 1 : 0);
    }
    int week()
    {
        int Y = y, M = m;
        if (m == 1 || m == 2)
        {
            Y--;
            M += 12;
        }
        int W = (d + M * 2 + 3 * (M + 1) / 5 + Y + Y / 4 - Y / 100 + Y / 400) % 7;
        return W + 1;
    }
    Date() {}
    //定义输出构造函数
    Date(int yy, int mm, int dd) { y = yy; m = mm; d = dd; }

    //定义结构体函数getNext(),获得后一天的日期

    Date getNext()
    {
        //如果这个天数小于该月的最大天数,则将该天数加1
        Date t(y, m, d);
        if (d<dayOfMonth[leap()][m])
            t.d += 1;
        //如果day为某月最后一天,则比较日期,如果month小于12月,则月份加1
        //并且将日设为1
        else if (m<12)
        {
            t.m += 1;
            t.d = 1;
        }
        //月和日为12.31则年往上加,月和日均设为1月1日
        else
        {
            t.y += 1;
            t.m = 1;
            t.d = 1;
        }
        return t;
    }
    //判断是否为证券处理的日期
    //如果这天是周六周日则不为处理日期,如果这天是元旦、五一、十一也不为处理日期
    bool dealDay()
    {
        if (week() == 6 || week() == 7)
            return false;
        if (m == 1 && d == 1 || m == 5 && d >= 1 && d <= 3 || m == 10 && d >= 1 && d <= 7)
            return false;
        return true;
    }
    //判断是否为周末
    bool isWeekend()
    {
        return week() == 6 || week() == 7;
    }
};

//判断这两天是否为相等的日期,如果年月日均相等,则是相同的日期

bool equals(Date d1, Date d2)
{
    return d1.y == d2.y&&d1.m == d2.m&&d1.d == d2.d;
}

//判断一年中有多少天交易日

int ansOfYear(int year)
{
    bool isleap = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
    int res = (isleap ? 366 : 365), t1, t2, t3 = 0, i;
    //一年有52周,这样有104天的周末
    t1 = 104;
    //如果是闰年,一年就有52周余两天,即余12.30与12.31
    if (isleap)
    {
        //如果12.30为周末,则非交易日多一天,同理12.31
        if (Date(year, 12, 30).isWeekend())
            t1 += 1;
        if (Date(year, 12, 31).isWeekend())
            t1 += 1;
    }
    //如果是平年的话,52周多1天,即12.31如果是周末则非交易日多一天
    else
    {
        if (Date(year, 12, 31).isWeekend())
            t1 += 1;
    }

    //元旦+五一+国庆==11天的假期不交易
    t2 = 11;
    //判断这三个假期是否和周末冲突,冲突的有几天
    if (Date(year, 1, 1).isWeekend())
        t3 += 1;
    for (i = 1; i<4; i++)
        if (Date(year, 5, i).isWeekend())
            t3 += 1;
    for (i = 1; i<8; i++)
        if (Date(year, 10, i).isWeekend())
            t3 += 1;
    //计算一年中多少个交易日
    res = res - t1 - t2 + t3;
    return res;
}

int main()
{
    int n, res = 0, i;
    Date d1, d2, t;
    scanf("%d", &n);
    while (n--)
    {
        res = 0;
        //输入两个日期
        scanf("%d-%d-%d %d-%d-%d", &d1.y, &d1.m, &d1.d, &d2.y, &d2.m, &d2.d);
        //如果两个日期之间相差小于等于一年,则直接计算日期差
        //起始日期为第一个日期,终止日期为第二个日期,用getNext()来计算后一天的//日期,并且如果是交易日的话,res++
        if (d2.y - d1.y <= 1)
        {
            for (t = d1; !equals(t, d2.getNext()); t = t.getNext())
                if (t.dealDay())
                    res += 1;
        }
        //如果两个日期相差一年以上,则先计算第一个日期到下一年1.1之前的交易日
        //再计算第二个日期的从1.1到该日期的交易日数
        //最后再计算二者之间相差的年数之间的交易日
        else
        {
            for (t = d1; !equals(t, Date(d1.y + 1, 1, 1)); t = t.getNext())
                if (t.dealDay())
                    res += 1;
            for (t = Date(d2.y, 1, 1); !equals(t, d2.getNext()); t = t.getNext())
                if (t.dealDay())
                    res += 1;
            for (i = d1.y + 1; i<d2.y; i++)
                res += ansOfYear(i);
        }
        printf("%d\n", res);
    }
    return 0;
}
//代码来源于网络,注意消化理解

后续待补充….

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值