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