Skip to content

Pro3

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

#include <bits/stdc++.h>

using namespace std;

const int days_sum[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
const int mon_day[] = {29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const string mon_name[] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
const string week_name[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

map<string, int> dict;

void init()
{
    for(int i = 1; i < 13; ++i) dict.insert(make_pair(mon_name[i], i));
    for(int i = 0; i < 7; ++i) dict.insert(make_pair(week_name[i], i));
}

// 如果是'12',返回12; 如果是'Jan',返回1
int my_stoi(string str)
{
    if(isdigit(str[0])) return stoi(str);
    transform(str.begin(), str.end(), str.begin(), ::toupper);
    return dict[str];
}

bool is_leapyear(int year)
{
    return !(year%400) || !(year%4) && (year%100);
}

bool is_day_legal(int year, int month, int day)
{
    if(is_leapyear(year) && month == 2) return day < 30 && day > 0;
    return day <= mon_day[month] && day > 0;
}

int query_week(int year, int month, int day)
{
    int a = (year - 1970);
    int days = a * 365 + (a + 1) / 4 + days_sum[month] + day;

    if(month > 2 && is_leapyear(year)) days++;
    return (days + 3) % 7;
}

struct Time
{
    // int year, month, day, hour, min;
    int save[5];
    Time(){}

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

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

        return false;
    }
};

void deal_with_no_comma(bool* arr, int arr_size, string str)
{
    int pos = str.find('-');
    if(pos != -1)
    {
        // 处理: 12-34
        int l_value = my_stoi(str.substr(0, pos));
        int r_value = my_stoi(str.substr(pos + 1));

        while(l_value <= r_value) { arr[l_value] = true; ++l_value; }
    }else
    {
        // 如果没有'-', 必定为: 12
        arr[my_stoi(str)] = true;
    }
}

void deal_with_comma(bool* arr, int arr_size, string str)
{
    if(str[0] == '*')
    {
        memset(arr, true, arr_size * sizeof(bool));
        return;
    }

    while(true)
    {
        int pos = str.find(','); 
        if(pos != -1)
        {
            string sub = str.substr(0, pos);
            deal_with_no_comma(arr, arr_size, sub);
            str = str.substr(pos + 1);
        }else
        {
            deal_with_no_comma(arr, arr_size, str);
            break;
        }
    }
}

struct Thing
{
    bool hour_arr[24], min_arr[60];
    bool mon_arr[13], day_arr[32];
    bool week_arr[7];
    string name;

    bool this_day_ok(Time& time)
    {
        return mon_arr[time.save[1]] && day_arr[time.save[2]]
            && week_arr[ query_week(time.save[0], time.save[1], time.save[2]) ];
    }

    bool this_time_ok(Time& time)
    {
        return this_day_ok(time) && hour_arr[time.save[3]] && min_arr[time.save[4]];
    }

    // 确保今天合法
    bool get_next_time_this_day(int h, int m, Time& time)
    {
        int index = h * 60 + m;
        while(++index < 24 * 60)
        {
            if(hour_arr[index/60] && min_arr[index%60])
            {
                time.save[3] = index/60; time.save[4] = index%60;
                return true;
            }
        }
        return false;
    }

    // 找到下一个合法的天
    bool get_next_day_this_year(int year, int m, int d, Time& time)
    {
        int index = m * 32 + d;
        while(++index < 13 * 32)
        {
            if(mon_arr[index/32] && day_arr[index%32])
            {
                if(!is_day_legal(year, index/32, index%32)) continue;
                if(!week_arr[ query_week(year, index/32, index%32) ]) continue;

                time.save[0] = year; time.save[1] = index/32; time.save[2] = index%32;
                return true;
            }
        }
        return false;
    }

    Thing(string str)
    {
        stringstream ss(str);
        string min, hour, day, mon, week, name; 
        ss >> min >> hour >> day >> mon >> week >> name;
        memset(hour_arr, false, sizeof(hour_arr));
        memset(min_arr, false, sizeof(min_arr));
        memset(mon_arr, false, sizeof(mon_arr));
        memset(day_arr, false, sizeof(day_arr));
        memset(week_arr, false, sizeof(week_arr));
        deal_with_comma(min_arr, 60, min);
        deal_with_comma(hour_arr, 13, hour);
        deal_with_comma(day_arr, 32, day);
        deal_with_comma(mon_arr, 13, mon);
        deal_with_comma(week_arr, 7, week);
        this->name = name;
    }

    Time find_next_time(Time begin_time)
    {
        Time time{}; 
        int year = begin_time.save[0]; int month = begin_time.save[1]; int day = begin_time.save[2];
        int hour = begin_time.save[3]; int minute = begin_time.save[4];

        for(int i = 0; i < 3; ++i) time.save[i] = begin_time.save[i];

        if( !this_day_ok(begin_time) || !get_next_time_this_day(hour, minute, time) )
        {
            if( !get_next_day_this_year(year, month, day, time) )
            {
                while(!get_next_day_this_year(++year, 1, 0, time));
            }
            get_next_time_this_day(0, -1, time);
        }
        return time;
    }
};


struct HeapNode
{
    int index; Time time;
    bool operator < (const HeapNode& other) const
    {
        if(time < other.time) return true;
        if(other.time < time) return false;
        return index < other.index;
    }
};

int main()
{
//     freopen("in.txt", "r", stdin);
    init();
    int n; string str01, str02;
    cin >> n >> str01 >> str02;
    Time hi(str01), lo(str02);

    vector<HeapNode> Q;
    vector<string> thing_name;
    string str03; cin.get();
    for(int i = 0; i < n; ++i)
    {
        getline(cin, str03); Thing cur(str03);

        thing_name.push_back(cur.name);
        Time this_time = (cur.this_time_ok(hi)) ? hi : cur.find_next_time(hi);

        while(this_time < lo) {
            Q.push_back({i, this_time});
            this_time = cur.find_next_time(this_time);
        }
    }

    sort(Q.begin(), Q.end());

    for(auto x : Q)
    {
        Time time = x.time;
        cout << time.save[0];
        for(int i = 1; i < 5; ++i) cout << setw(2) << setfill('0') << time.save[i];
        cout << " " << thing_name[x.index] << endl;
    }

    return 0;
}