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;
}
CCF-CSP题解 201712-3 Crontab的更多相关文章
- CCF CSP 201703-3 Markdown
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-3 Markdown 问题描述 Markdown 是一种很流行的轻量级标记语言(l ...
- CCF CSP 201312-3 最大的矩形
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-3 最大的矩形 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i( ...
- CCF CSP 201609-3 炉石传说
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201609-3 炉石传说 问题描述 <炉石传说:魔兽英雄传>(Hearthston ...
- CCF CSP 201403-3 命令行选项
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-3 命令行选项 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些 ...
- CCF CSP 201709-4 通信网络
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201709-4 通信网络 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M ...
- CCF CSP 201409-3 字符串匹配
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201409-3 字符串匹配 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那 ...
- CCF CSP 201503-3 节日
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-3 节日 问题描述 有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形 ...
- CCF CSP 201509-2 日期计算
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201509-2 日期计算 问题描述 给定一个年份y和一个整数d,问这一年的第d天是几月几日? ...
- CCF CSP 201604-2 俄罗斯方块
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201604-2 俄罗斯方块 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游 ...
- CCF CSP 201512-2 消除类游戏
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201512-2 消除类游戏 问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行 ...
随机推荐
- PHP编程20大效率要点
1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row[’id’] 的速度是$row[id]的7倍. 3.echo 比 print 快,并且使用ech ...
- Linux(CentOS65)
首先下载VMware,然后下载CentOS镜像文件,VM的版本尽量高一点,因为软件一般都有向下兼容性,如果版本太低,可能匹配不了CentOS. 安装VMTools工具 主要用于虚拟主机显示优化与调整, ...
- cnpm镜像安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
- 同步工具类 CountDownLatch 和 CyclicBarrier
在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...
- EFK教程(4) - ElasticSearch集群TLS加密通讯
基于TLS实现ElasticSearch集群加密通讯 作者:"发颠的小狼",欢迎转载 目录 ▪ 用途 ▪ ES节点信息 ▪ Step1. 关闭服务 ▪ Step2. 创建CA证书 ...
- 小熊派IoT开发板系列教程正式发布——免费学习
[摘要] 小熊派开源社区针对小熊派IoT开发板首次规划了小熊派未来的系列教程.从基础到进阶的设计,可适应具有不同基础的开发者,通过该系列教程的学习,开发者能够轻松掌握IoT产品的开发.该系列教程包括单 ...
- docker tomcat镜像部署springbootwar包
springboot打war包 1.在pom文件中增加插件 <build> <finalName>xx</finalName> <plugins> &l ...
- Python的Requests库基本方法函数
一.Requests 库的七个常用函数: 1. requests.request(method,url,**kwargs) :method:请求方式,对应get/put/post等七种 :拟获取页面的 ...
- iOS包管理工具Cocoapods的安装与使用
转自:http://www.sxt.cn/u/10014/blog/6448 在我们开发移动应用的时候,一般都会使用到第三方工具,而由于第三方类库的种类繁多,我们在项目中进行管理也会相对麻烦,所以此时 ...
- 移动开发在路上-- IOS移动开发系列 网络交互四(1)
最近一段时间上班忙的没日没夜的,不是披星戴月,就是头天早上出门,第二天早上回家...一直没出处时间来更新博客,码农之苦,说了都是泪,废话不多说,直接本主题,经过之前三篇的讲述,ios开发的东西大家或多 ...