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

CCF-CSP题解 201712-3 Crontab的更多相关文章

  1. CCF CSP 201703-3 Markdown

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-3 Markdown 问题描述 Markdown 是一种很流行的轻量级标记语言(l ...

  2. CCF CSP 201312-3 最大的矩形

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-3 最大的矩形 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i( ...

  3. CCF CSP 201609-3 炉石传说

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201609-3 炉石传说 问题描述 <炉石传说:魔兽英雄传>(Hearthston ...

  4. CCF CSP 201403-3 命令行选项

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-3 命令行选项 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些 ...

  5. CCF CSP 201709-4 通信网络

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201709-4 通信网络 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M ...

  6. CCF CSP 201409-3 字符串匹配

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201409-3 字符串匹配 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那 ...

  7. CCF CSP 201503-3 节日

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-3 节日 问题描述 有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形 ...

  8. CCF CSP 201509-2 日期计算

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201509-2 日期计算 问题描述 给定一个年份y和一个整数d,问这一年的第d天是几月几日? ...

  9. CCF CSP 201604-2 俄罗斯方块

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201604-2 俄罗斯方块 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游 ...

  10. CCF CSP 201512-2 消除类游戏

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201512-2 消除类游戏 问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行 ...

随机推荐

  1. Bran的内核开发教程(bkerndev)-08 中断服务程序(ISR)

    中断服务程序(ISR)   中断服务程序(ISR)用于保存当前处理器的状态, 并在调用内核的C级中断处理程序之前正确设置内核模式所需的段寄存器.而工作只需要15到20行汇编代码来处理, 包括调用C中的 ...

  2. Error: invalid "instanceof" keyword value Promise的解决方法

    执行npm run dev 时,发现错误 Error: invalid "instanceof" keyword value Promise 经过一番查找,发现原因是webpack ...

  3. Java——内部类详解

    说起内部类,大家肯定感觉熟悉又陌生,因为一定在很多框架源码中有看到别人使用过,但又感觉自己使用的比较少,今天我就带你具体来看看内部类. 内部类基础 所谓内部类就是在类的内部继续定义其他内部结构类. 在 ...

  4. 【Oracle】Oracle ASM管理监控命令

    目录 Oracle ASM管理监控命令 目的: 1.查看磁盘组 2.查看目前归档 3.查看ASM的磁盘路径 4. asmcmd Oracle ASM管理监控命令 目的: 查看目前Oracle ASM相 ...

  5. GeoServer 查询sql视图

    说明: 最近项目中遇到一个需求,需要统计管网的长度,但管网数据量非常大,前端用openlayers接口统计直接就奔溃了. 后尝试使用调后台接口查数据库的方式,虽然可行但是又要多一层与后台交互的工作. ...

  6. 使用MongoDB的Spring Boot和MongoTemplate教程

    在本教程中,我们将构建一个Spring Boot应用程序,该应用程序演示如何使用MongoTemplate API访问MongoDB数据库中的数据. 对于MongoDB,我们将使用mLab,它提供了M ...

  7. HDFS之NameNode

    NameNode&Secondary NameNode工作机制 1)第一阶段:namenode启动 (1)第一次启动namenode格式化后,创建fsimage和edits文件.如果不是第一次 ...

  8. 【2018寒假集训 Day2】【动态规划】钱币兑换(exchange)(自己翻译的2333)

    钱币兑换(exchange) 问题描述: Dave偶然获得了未来几天的美元(dollars)与马克(marks)之间的兑换率.例如Dave开始有100marks,请编写个程序帮助Dave找出最好的买卖 ...

  9. linux basic

    一:date 语法: 打印日期:date [OPTION].....  [+FORMAT] 设定日期:date [MMDDhhmm] [[cc][YY][.ss] 创建带实时日期的文件 touch $ ...

  10. CentOS 7 安装 dnsmasq 服务 实现内网DNS

    目录 安装 配置 服务管理 测试解析 安装 废话不多述,上来就安装 yum install -y bind-utils dnsmasq 配置 [root@jenkins ~]# rpm -ql dns ...