当前位置:网站首页>201712-3 CCF Crontab满分题解
201712-3 CCF Crontab满分题解
2022-08-03 18:27:00 【一只可爱的小猴子】
原题链接
Crontab原题链接
解题思路
题目意思就是输出每一时刻能被执行的命令
那么如果时间允许的话,可以直接把时间枚举一遍,每个时间判断一下该任务能否执行即可
其实时间1970010100,结束时间209912312359
算下来是六千万多分钟,10s时间足够,因此暴力枚举
写一个时钟结构体,模拟时间的递增,并且能将时间进行格式化输出
写一个任务结构体,存储该任务能执行的时间,当minute,hour, day, month, week都满足时,将时间和命令输出
解题技巧
时间结构体的写法应记住,可以看作是一个模板
掌握如何快速将多个int合并成一个字符串(sprintf)
如何将字符串分割存储在多个int中(sscanf)
判断时间点是否可执行时,可以采用结构体加时间数组的存储格式
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
int months[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
struct Timer
{
int minute, hour, dayofmonth, month, dayofweek, year;
//构造函数要同名
Timer(string t)
{
//能自动去除前缀零,将字符串内容写入数字中
sscanf(t.c_str(), "%04d%02d%02d%02d%02d", &year, &month, &dayofmonth, &hour, &minute);
}
int is_leap()
{
if (year % 400 == 0 || (year % 4 == 0 && year % 100)) return 1;
else return 0;
}
int getdays()
{
if (month == 2) return months[2] + is_leap();
else return months[month];
}
void next()
{
if ( ++ minute == 60)
{
minute = 0;
if ( ++ hour == 24)
{
hour = 0;
dayofweek = (dayofweek + 1) % 7; //位置不要写错
if ( ++ dayofmonth > getdays())
{
dayofmonth = 1;
if ( ++ month == 13)
{
month = 1;
year ++;
}
}
}
}
}
//重载小于符号,是指自己小于对方,不要写反
bool operator< (const Timer & t)const
{
if (t.year != year) return year < t.year;
if (t.month != month) return month < t.month;
if (t.dayofmonth != dayofmonth) return dayofmonth < t.dayofmonth;
if (t.hour != hour) return hour < t.hour;
return minute < t.minute;
}
string to_string()
{
char str[20];
//把一串整数打印到字符串中,而不是显示在终端屏幕上,所以需要返回字符串
sprintf(str, "%04d%02d%02d%02d%02d", year, month, dayofmonth, hour, minute);
return str;
}
};
struct Text
{
//判断某刻时间能否做某事,时间允许遍历时,可以采用这样的数组存法
bool minute[60], hour[24], dayofmonth[32], month[13], dayofweek[7];
string command;
bool check(Timer & t)
{
return minute[t.minute] && hour[t.hour] && dayofmonth[t.dayofmonth] &&
month[t.month] && dayofweek[t.dayofweek];
}
}text[20];
unordered_map <string, int> book;
void Init()
{
string a[19] = {
"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug",
"sep", "oct", "nov", "dec", "mon", "tue", "wed", "thu", "fri", "sat", "sun"};
int b[19] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 0};
for (int i = 0; i < 19; i ++)
{
book[a[i]] = b[i];
}
}
int getnum(string str)
{
if (str[0] >= '0' && str[0] <= '9') return stoi(str);
else
{
//转换大小写的方法要记住掌握
transform(str.begin(), str.end(), str.begin(), ::tolower);
return book[str];
}
}
void work(string str, bool st[], int len)
{
if (str == "*")
{
for (int i = 0; i < len; i ++) st[i] = true;
return ;
}
for (int i = 0; i < str.size(); i ++)
{
int j = str.find(',', i);
if (j == -1) j = str.size();
string tmp = str.substr(i, j - i);
int k = tmp.find('-');
if (k == -1)
{
st[getnum(tmp)] = true;
}
else
{
int l = getnum(tmp.substr(0, k));
int r = getnum(tmp.substr(k + 1));
for (int u = l; u <= r; u ++) st[u] = true;
}
i = j;
}
}
int main()
{
Init();
int n;
string s, t;
cin >> n;
cin >> s >> t;
for (int i = 0; i < n; i ++)
{
string minute, hour, dayofmonth, month, dayofweek, command;
cin >> minute >> hour >> dayofmonth >> month >> dayofweek >> command;
//传数组名,相当于传首地址了吗,竟然可以直接用函数修改数组
work(minute, text[i].minute, 60);
work(hour, text[i].hour, 24);
work(dayofmonth, text[i].dayofmonth, 32);
work(month, text[i].month, 13);
work(dayofweek, text[i].dayofweek, 7);
text[i].command = command;
}
Timer cur("197001010000"), start(s), end(t);
cur.dayofweek = 4;
while (cur < end)
{
//不能使用大于等于,因为之重载了小于号
if (!(cur < start))
{
for (int i = 0; i < n; i ++)
{
if (text[i].check(cur))
{
cout << cur.to_string() << " " << text[i].command << endl;
}
}
}
cur.next();
}
return 0;
}
边栏推荐
- [数据集][VOC]老鼠数据集voc格式3001张
- Atomic Wallet已支持TRC20-USDT
- 使用安全浏览器将网页保存为pdf的方法步骤
- 云图说丨初识华为云微服务引擎CSE
- 【牛客在线OJ】-字符逆序
- 懵逼!阿里一面被虐了,幸获内推华为技术四面,成功拿到offer,年薪40w
- warnings.warn(“Title is more than 31 characters. Some applications may not be able to read the file
- 剑指Offer 56.数组中数字出现的次数
- xxl-job 实现email发送警告的代码解析(一行一行代码解读)
- 【美丽天天秒】链动2+1模式开发
猜你喜欢
随机推荐
POJ 3041 Asteroids(最大匹配数=最小点覆盖)
tree命令:以树的形式列出目录中的文件
大佬们,flinkcdc 2.2 版本采集sqlserver只能采集到全量的数据,不能采集到增量的数
超T动力 焕“芯”出发 | 中国重汽专属定制版WP14T产品闪耀登场
Cyanine5.5 alkyne|Cy5.5 alkyne|1628790-37-3|Cy5.5-ALK
Oracle备份的几种方式
架构基本概念和架构本质
Flask框架——项目可安装化
15、学习MySQL NULL 值处理
云图说丨初识华为云微服务引擎CSE
online 方式创建索引触发trigger怎么办?
想要防止数据泄漏,如何选择国产浏览器?
谷歌浏览器安装插件教程步骤,开发用这2个插件工作效率倍增
STM32——LCD—FSMC原理简介
CodeTON Round 2 (Div. 1 + Div. 2, Rated, Prizes), problem: (D) Magical Array
揭秘deepin 23,从这里开始!
MySQL database account management and optimization
什么是鉴权?一篇文章带你了解postman的多种方式
基于PHP7.2+MySQL5.7的回收租凭系统
使用range-based for循环的注意事项