Skip to content

Pro3_WA_65

原始文件为 CPP 代码,本文是转换后的 Markdown 文件。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <map>
#include <vector>
#include <stack>

#define FOUR_YEAR 365*4+1
#define ONE_YEAR 365

using namespace std;

// 月份表
int month_table[12];
int time_max[5] = {0,12,30,24,60};
int month_max[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
map<string,int> month_map;

// 强制转为小写
string tolower(string s)
{
    string result = "";
    int len = s.length();
    for(int i=0;i<len;++i)
    {
        (s[i]>='A' && s[i]<='Z') ? (result += (s[i]-('A'-'a'))) : (result += s[i]);
    }

    return result;
}

// 处理只有-的字符串,利用引用改变值
void deal_with_underline(string str,int &lo,int &hi)
{
    int pos = str.find('-');
    if(pos != -1)
    {
        string str_1 = str.substr(0,pos);
        string str_2 = str.substr(pos+1,str.size());

        (str_1.find_first_not_of("0123456789") != -1) ? (lo = month_map[tolower(str_1)]) : (lo = stoi(str_1));
        (str_2.find_first_not_of("0123456789") != -1) ? (hi = month_map[tolower(str_2)]) : (hi = stoi(str_2));
    }else
    {
        (str.find_first_not_of("0123456789") != -1) ? (lo = month_map[tolower(str)]) : (lo = stoi(str));
        hi = lo;
    }
}

// 确切的时间
class Time
{
public:
    int time[5];
    int week;

    Time(string str)
    {
        time[0] = stoi(str.substr(0,4));
        for(int i=1;i<5;++i)
            time[i] = stoi(str.substr(2+2*i,2));

        time[4]++;
        time[3]++;
    }

    // 每次加一分钟
    Time& operator++()
    {
        int save_day = time[2];
        (time[0] % 4) ?  month_max[1] = 28 : month_max[1] = 29;
        for(int i=4;i>0;--i)
        {
            if(i==2)
            {
                time_max[i] = month_max[time[1]-1];
            }
            time[i] = (time[i]%time_max[i])+1;

            if(time[i] != 1) break;
            if(1 == i) time[i-1] ++;
        }

        // 如果天数加一那么周数就要加一
        if(save_day != time[2]) week = week%7 + 1;
    }

    bool operator<(const Time& other)
    {
        for(int i=0;i<5;++i)
            if(time[i]!=other.time[i])
                return time[i]<other.time[i];
    }

    void Print()
    {
        printf("%d",time[0]);
        for(int i=1;i<5;++i)
            (3==i || 4==i) ? printf("%02d",time[i]-1) : printf("%02d",time[i]);
    }
};

// 命令类
class Order
{
public:
    // true表示可以
    bool flag[5][65];
    // 命令
    string cmd;

    Order(string str)
    {
        // 初始化
        for(int i=0;i<5;i++)
            for(int j=0;j<65;j++)
                flag[i][j] = false;

        // 处理数据
        for(int i=0;i<5;++i)
        {
            int len = str.find(' ');
            string sub = str.substr(0,len);

            int pos = sub.find('*');

            if(pos != -1)
            {
                for(int j=0;j<65;j++)
                    flag[i][j] = true;
            }else
            {
                int lo,hi;
                while((pos = sub.find(',')) != -1)
                {
                    string temp = sub.substr(0,pos);
                    sub = sub.substr(pos+1,105);

                    deal_with_underline(temp,lo,hi);

                    if(1 == i || 0 == i || 4 == i) { lo++; hi++; }

                    while(lo <= hi)
                        flag[i][lo++] = true;
                }
                /* cout << sub << endl; */

                deal_with_underline(sub,lo,hi);
                if(4 == i || 1 == i || 0 == i) { lo++; hi++; }

                /* cout << i << " " << lo << " " << hi << endl; */
                while(lo <= hi)
                    flag[i][lo++] = true;

            }

            str = str.substr(len+1,105);
        }
        cmd = str;
    }

    bool isExecute(Time& now)
    {
        for(int i=0;i<4;++i)
        {
            /* cout << now.time[4-i] << endl; */
            if(!flag[i][now.time[4-i]]) return false;
        }

        return flag[4][now.week];
    }

    void Print()
    {
        cout << cmd;
    }
};

// 给定时间,计算第几周
int computeWeek(Time& t)
{
    int result = 0;

    // 先根据年份计算天数
    result += (t.time[0]-1970)/4*1461;
    /* cout << (t.time[0]-1970)/4*FOUR_YEAR << endl; */
    result += (t.time[0]-1970)%4*365;
    if((t.time[0]-1970)%4 == 3) result++;

    // 根据月份计算天数
    result += month_table[t.time[1]-1];
    if((t.time[1] > 2) && !(t.time[0]%4)) result++;

    // 根据时间计算天数
    result += t.time[2]-1;

    // 计算周数
    result = (result + 3) % 7 + 1;

    // 改成周日为1的形式
    result = result%7 + 1;
    return result;
}

// 提前打表
void compute_month_table()
{
    month_table[0] = 0;
    month_table[1] = 31;
    month_table[2] = 31+28;
    month_table[3] = month_table[2]+31;
    month_table[4] = month_table[3]+30;
    month_table[5] = month_table[4]+31;
    month_table[6] = month_table[5]+30;
    month_table[7] = month_table[6]+31;
    month_table[8] = month_table[7]+31;
    month_table[9] = month_table[8]+30;
    month_table[10] = month_table[9]+31;
    month_table[11] = month_table[10]+30;
}

// 名称对应表
void compute_month_map()
{
    month_map["jan"] = 1;
    month_map["feb"] = 2;
    month_map["mar"] = 3;
    month_map["apr"] = 4;
    month_map["may"] = 5;
    month_map["jun"] = 6;
    month_map["jul"] = 7;
    month_map["aug"] = 8;
    month_map["sep"] = 9;
    month_map["oct"] = 10;
    month_map["nov"] = 11;
    month_map["dec"] = 12;
    month_map["sun"] = 0;
    month_map["mon"] = 1;
    month_map["tue"] = 2;
    month_map["wed"] = 3;
    month_map["thu"] = 4;
    month_map["fri"] = 5;
    month_map["sat"] = 6;
}
vector<Order*> container;

int main(int args,char* argv[])
{
    freopen("in.txt","r",stdin);
    compute_month_table();
    compute_month_map();

    int n;
    string s,t;
    cin >> n >> s >> t;
    string str;
    cin.get();

    Time begin(s);
    Time end(t);

    begin.week = computeWeek(begin);
    end.week = computeWeek(end);

    for(int i=0;i<n;++i)
    {
        getline(cin,str);

        Order* now = new Order(str);
        container.push_back(now);
    }

    /* cout << container.size() << endl; */
    /* Order *c = container[2]; */
    /* for(int i=0;i<5;i++) */
    /* { */
    /*     for(int j=0;j<65;j++) */
    /*     { */
    /*         cout << c->flag[i][j] << " "; */
    /*     } */
    /*     cout << endl; */
    /* } */

    /* c->isExecute(begin); */

    while(begin < end)
    {
        for(auto x:container)
        {
            if(x->isExecute(begin))
            {
                begin.Print();
                cout << " ";
                x->Print();
                cout << endl;
            }
        }
        ++begin;
    }
    return 0;
}