Fork me on github

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] = '\0';
                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] = '\0';
                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\n", node.time, command[node.comId]);
    }

    return 0;
}

posted @ 2019-07-23 09:17  acboyty  阅读(779)  评论(0编辑  收藏  举报