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

    记录工作中遇到的问题,分享出来: 前端时间在提交项目到svn遇到一个问题, 提交的时候提示:文件已经锁定!如下图: 原因是我之前提交的时候不小心中途停了,导致文件被锁,然后也没在意那么多, 趁着今天有 ...

  2. SCAU-1076 K尾相等数

    代码借鉴SCAU-OJ(感谢!!) 题目:1076 K尾相等数 时间限制:500MS  内存限制:65536K提交次数:251 通过次数:80 题型: 编程题   语言: G++;GCC   Desc ...

  3. mysql锁简谈

    1.mysql锁, 作用:解决因资源共享而造成的并发问题. 实例:买最好一件衣服X A: X 买: X加锁----->试衣服……下单……付款……打包….------>X解锁 B: X 买: ...

  4. php如何处理大数据高并发

    大数据解决方案 使用缓存: 使用方式:1,使用程序直接保存到内存中.主要使用Map,尤其ConcurrentHashMap. 使用缓存框架.常用的框架:Ehcache,Memcache,Redis等. ...

  5. vue JS实现监听浏览器返回按键事件

    // 这个是监听浏览器回退键的returnButton () { let vm = this; $(document).ready(function () { if (window.history & ...

  6. sed和awk的简单使用

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以  行 为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法. 语法: sed [-nefri] ‘ ...

  7. day20191113笔记

    默写:程序=数据结构+操作系统. 一.文件上传 1.导入commons-fileupload.jar commons-io.jar 2.配置 <bean id="multipartRe ...

  8. Alertmanager 部署配置

    目录 前言 源码安装 配置 启动 配置prometheus监控Alertmanager 修改prometheus配置 重新加载配置文件 配置测试告警 修改prometheus配置 重新加载配置文件 测 ...

  9. 【SSL1457】翻币问题

    题面: \[\Large\text{翻币问题}\] \[Time~Limit:1000MS~~Memory~Limit:65536K\] Description 有N个硬币(6<=N<=2 ...

  10. php踩过的那些坑(3) 数据类型转换

    一.前方有坑 php属于弱类型语言,不会强迫工程师在使用变量之前先声明变量类型,开发时爽了,但是也带来不少的坑.下面就举一个坑的例子: 例1: $str = ‘haodaquan'; echo ($s ...