• CCF-CSP题解 201712-3 Crontab


    做完一定要仔仔细细地看一遍题目再交,之后发现坑点只能追悔莫及。比如这次“英文缩写(不区分大小写)”(OwQ)

    给定多个周期性执行的任务,每个任务调度执行有时间的要求。求给定时间范围内,所有任务调度执行的时间点。

    又是熟悉的字符串处理hhh。用一个(<minute,hour,dayOfMonth,month,dayOfWeek>)结构体存储一个cron配置信息。每种元素的处理方式几乎一样。重点是处理好(,)(-)(*)这三个符号,同时注意后两个元素有英文缩写的表达方式。

    我的想法是穷举法挨个找出每个cron配置信息对应的所有时间。也就是枚举符合要求的(year)(month)(dayOfMonth),然后判断这一天对应的(dayOfWeek)是否符合要求,若符合,接着枚举符合要求的(hour)(minute)。最后看枚举出的时间是否在([s,t))范围内,若在,将该时间(time)与cron的(id)组合成一个结构体丢到优先队列中(结构体排序定义一下这样弹出顺序就对了)。

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 20;
    
    using namespace std;
    
    struct tCron
    {
        int minute[60];
        int hour[24];
        int dayOfMonth[32];
        int month[13];
        int dayOfWeek[7];
        tCron()
        {
            memset(minute, 0, sizeof(minute));
            memset(hour, 0, sizeof(hour));
            memset(dayOfMonth, 0, sizeof(dayOfMonth));
            memset(month, 0, sizeof(month));
            memset(dayOfWeek, 0, sizeof(dayOfWeek));
        }
    };
    tCron cron[maxn+5];
    
    char command[maxn+5][105];
    
    int monthToNumber(char s[])
    {
        for (int i = 0; i <= 2; i++)
            s[i] = tolower(s[i]);
        if (strcmp(s, "jan") == 0)
            return 1;
        if (strcmp(s, "feb") == 0)
            return 2;
        if (strcmp(s, "mar") == 0)
            return 3;
        if (strcmp(s, "apr") == 0)
            return 4;
        if (strcmp(s, "may") == 0)
            return 5;
        if (strcmp(s, "jun") == 0)
            return 6;
        if (strcmp(s, "jul") == 0)
            return 7;
        if (strcmp(s, "aug") == 0)
            return 8;
        if (strcmp(s, "sep") == 0)
            return 9;
        if (strcmp(s, "oct") == 0)
            return 10;
        if (strcmp(s, "nov") == 0)
            return 11;
        return 12;
    }
    
    int weekToNumber(char s[])
    {
        for (int i = 0; i <= 2; i++)
            s[i] = tolower(s[i]);
        if (strcmp(s, "sun") == 0)
            return 0;
        if (strcmp(s, "mon") == 0)
            return 1;
        if (strcmp(s, "tue") == 0)
            return 2;
        if (strcmp(s, "wed") == 0)
            return 3;
        if (strcmp(s, "thu") == 0)
            return 4;
        if (strcmp(s, "fri") == 0)
            return 5;
        return 6;
    }
    
    bool isLunar(int year)
    {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }
    
    int monthDay[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    int getDayOfWeek(int year, int month, int dayOfMonth)
    {
        int totDay = 0;
        for (int i = 1970; i <= year - 1; i++)
        {
            if (isLunar(i))
                totDay += 366;
            else
                totDay += 365;
        }
        for (int i = 1; i <= month - 1; i++)
        {
            if (isLunar(year) && i == 2)
                totDay += 29;
            else
                totDay += monthDay[i];
        }
        totDay += dayOfMonth;
        return (3 + totDay % 7) % 7;
    }
    
    struct tNode
    {
        LL time;
        int comId;
        tNode(LL t, int c)
        {
            time = t;
            comId = c;
        }
        bool operator < (const tNode &y) const
        {
            if (time == y.time)
                return comId > y.comId;
            return time > y.time;
        }
    };
    
    int main()
    {
        int n;
        LL s, t;
        scanf("%d%lld%lld", &n, &s, &t);
        for (int i = 1; i <= n; i++)
        {
            char temp[105];
            scanf("%s", temp);
            for (int j = 0, pre = -1, tmp = 0; ; j++)
            {
                if (temp[j] == '*')
                {
                    for (int k = 0; k <= 59; k++)
                        cron[i].minute[k] = 1;
                    break;
                }
                else if (temp[j] >= '0' && temp[j] <= '9')
                {
                    tmp = tmp * 10 + temp[j] - '0';
                }
                else if (temp[j] == ',')
                {
                    if (pre == -1)
                    {
                        cron[i].minute[tmp] = 1;
                        tmp = 0;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].minute[k] = 1;
                        pre = -1;
                        tmp = 0;
                    }
                }
                else if (temp[j] == '-')
                {
                    pre = tmp;
                    tmp = 0;
                }
                else
                {
                    if (pre == -1)
                    {
                        cron[i].minute[tmp] = 1;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].minute[k] = 1;
                    }
                    break;
                }
            }
            scanf("%s", temp);
            for (int j = 0, pre = -1, tmp = 0; ; j++)
            {
                if (temp[j] == '*')
                {
                    for (int k = 0; k <= 23; k++)
                        cron[i].hour[k] = 1;
                    break;
                }
                else if (temp[j] >= '0' && temp[j] <= '9')
                {
                    tmp = tmp * 10 + temp[j] - '0';
                }
                else if (temp[j] == ',')
                {
                    if (pre == -1)
                    {
                        cron[i].hour[tmp] = 1;
                        tmp = 0;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].hour[k] = 1;
                        pre = -1;
                        tmp = 0;
                    }
                }
                else if (temp[j] == '-')
                {
                    pre = tmp;
                    tmp = 0;
                }
                else
                {
                    if (pre == -1)
                    {
                        cron[i].hour[tmp] = 1;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].hour[k] = 1;
                    }
                    break;
                }
            }
            scanf("%s", temp);
            for (int j = 0, pre = -1, tmp = 0; ; j++)
            {
                if (temp[j] == '*')
                {
                    for (int k = 1; k <= 31; k++)
                        cron[i].dayOfMonth[k] = 1;
                    break;
                }
                else if (temp[j] >= '0' && temp[j] <= '9')
                {
                    tmp = tmp * 10 + temp[j] - '0';
                }
                else if (temp[j] == ',')
                {
                    if (pre == -1)
                    {
                        cron[i].dayOfMonth[tmp] = 1;
                        tmp = 0;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].dayOfMonth[k] = 1;
                        pre = -1;
                        tmp = 0;
                    }
                }
                else if (temp[j] == '-')
                {
                    pre = tmp;
                    tmp = 0;
                }
                else
                {
                    if (pre == -1)
                    {
                        cron[i].dayOfMonth[tmp] = 1;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].dayOfMonth[k] = 1;
                    }
                    break;
                }
            }
            scanf("%s", temp);
            for (int j = 0, pre = -1, tmp = 0; ; j++)
            {
                if (temp[j] == '*')
                {
                    for (int k = 1; k <= 12; k++)
                        cron[i].month[k] = 1;
                    break;
                }
                else if (temp[j] >= '0' && temp[j] <= '9')
                {
                    tmp = tmp * 10 + temp[j] - '0';
                }
                else if ((temp[j] >= 'a' && temp[j] <= 'z') ||
                         (temp[j] >= 'A' && temp[j] <= 'Z'))
                {
                    char mon[4];
                    mon[0] = temp[j];
                    mon[1] = temp[j+1];
                    mon[2] = temp[j+2];
                    mon[3] = '';
                    tmp = monthToNumber(mon);
                    j += 2;
                }
                else if (temp[j] == ',')
                {
                    if (pre == -1)
                    {
                        cron[i].month[tmp] = 1;
                        tmp = 0;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].month[k] = 1;
                        pre = -1;
                        tmp = 0;
                    }
                }
                else if (temp[j] == '-')
                {
                    pre = tmp;
                    tmp = 0;
                }
                else
                {
                    if (pre == -1)
                    {
                        cron[i].month[tmp] = 1;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].month[k] = 1;
                    }
                    break;
                }
            }
            scanf("%s", temp);
            for (int j = 0, pre = -1, tmp = 0; ; j++)
            {
                if (temp[j] == '*')
                {
                    for (int k = 0; k <= 6; k++)
                        cron[i].dayOfWeek[k] = 1;
                    break;
                }
                else if (temp[j] >= '0' && temp[j] <= '9')
                {
                    tmp = tmp * 10 + temp[j] - '0';
                }
                else if ((temp[j] >= 'a' && temp[j] <= 'z') ||
                         (temp[j] >= 'A' && temp[j] <= 'Z'))
                {
                    char mon[4];
                    mon[0] = temp[j];
                    mon[1] = temp[j+1];
                    mon[2] = temp[j+2];
                    mon[3] = '';
                    tmp = weekToNumber(mon);
                    j += 2;
                }
                else if (temp[j] == ',')
                {
                    if (pre == -1)
                    {
                        cron[i].dayOfWeek[tmp] = 1;
                        tmp = 0;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].dayOfWeek[k] = 1;
                        pre = -1;
                        tmp = 0;
                    }
                }
                else if (temp[j] == '-')
                {
                    pre = tmp;
                    tmp = 0;
                }
                else
                {
                    if (pre == -1)
                    {
                        cron[i].dayOfWeek[tmp] = 1;
                    }
                    else
                    {
                        for (int k = pre; k <= tmp; k++)
                            cron[i].dayOfWeek[k] = 1;
                    }
                    break;
                }
            }
            scanf("%s", command[i]);
        }
    
        priority_queue<tNode> q;
        for (int i = 1; i <= n; i++)
        {
            for (int year = (int)(s / 100000000LL); year <= (int)(t / 100000000LL); year++)
            {
                for (int month = 1; month <= 12; month++)
                {
                    if (cron[i].month[month])
                    {
                        for (int dayOfMonth = 1; dayOfMonth <= ((isLunar(year) && month == 2) ? 29 : monthDay[month]); dayOfMonth++)
                        {
                            if (cron[i].dayOfMonth[dayOfMonth] && cron[i].dayOfWeek[getDayOfWeek(year, month, dayOfMonth)])
                            {
                                for (int hour = 0; hour <= 23; hour++)
                                {
                                    if (cron[i].hour[hour])
                                    {
                                        for (int minute = 0; minute <= 59; minute++)
                                        {
                                            if (cron[i].minute[minute])
                                            {
                                                LL temp = 1LL * year * 100000000 + 1LL * month * 1000000 + 1LL * dayOfMonth * 10000 + 1LL * hour * 100 + 1LL * minute;
                                                if (temp < t && temp >= s)
                                                {
                                                    q.push(tNode(temp, i));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    
        while (!q.empty())
        {
            tNode node = q.top(); q.pop();
            printf("%lld %s
    ", node.time, command[node.comId]);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    Entity Framework Core系列教程-1-介绍
    火锅大队作品简介
    一号课题组作品简介
    Attract队作品简介
    华理时空之眼队作品简介
    热情致终队作品简介
    触摸阳光队作品简介
    PIE SDK水体指数法
    PIE SDK水深提取算法
    PIE SDK直方图统计法
  • 原文地址:https://www.cnblogs.com/acboyty/p/11229719.html
Copyright © 2020-2023  润新知