ccf-201712-3 Crontab(详解)

ccf-201712-3 Crontab(详解)


试题编号: 201712-3


试题名称: Crontab


时间限制: 10.0s


内存限制: 256.0MB


问题描述:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

样例输入

3 201711170032 201711222352
0 7 * * 1,3-5 get_up
30 23 * * Sat,Sun go_to_bed
15 12,18 * * * have_dinner

样例输出

201711170700 get_up
201711171215 have_dinner
201711171815 have_dinner
201711181215 have_dinner
201711181815 have_dinner
201711182330 go_to_bed
201711191215 have_dinner
201711191815 have_dinner
201711192330 go_to_bed
201711200700 get_up
201711201215 have_dinner
201711201815 have_dinner
201711211215 have_dinner
201711211815 have_dinner
201711220700 get_up
201711221215 have_dinner
201711221815 have_dinner


思路解析

关键词分析

解题步骤


code

#include <iostream>
#include <string>
#include <map>
#include <sstream>
#include <vector>
using namespace std;
struct note {
    string act;vector<int> num[6];
} nt;
map<string,int> mw;
int mon[12] = {31,28,31,30,31,30,31,31,30,31,30,31},tim[10]= {60,24,32,13,7,0,0,1,1,0};
int monr[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
long long start,end;
int n,date[2];
map<long long,vector<string> > action;
string temp;
int run(int i) {
    return (i%4==0&&i%100)||i%400==0;
}
string tolow(string a) {
    int i=0;while(i<a.size()) {a[i]=tolower(a[i]);i++;}
    return a;
}
int str2int(string a) {
    int b;if(a[0]>'9') {    b=mw[tolow(a)];} else { stringstream ss;ss << a;ss >> b;}
    return b;
}
void tostand(string a,vector<int> &b,int c) {
    if(a.size()<3) {
        if(a=="*") {for(int i=tim[c+5]; i<tim[c]; i++) {b.push_back(i);}} else {b.push_back(str2int(a));}
    } else {
        string ac;a+=",";
        int p0=-1,p1=a.find_first_of(",-"),t0,t1;
        while(p1>-1) {
            ac=a.substr(p0+1,p1-p0-1);t0=str2int(ac);
            if(a[p1]=='-') {
                p0=p1;p1=a.find_first_of(",-",p0+1);
                if(p1==-1) {p1=a.size();}
                ac=a.substr(p0+1,p1-p0-1);t1 =str2int(ac);
                for(int i=t0; i<t1+1; i++) {b.push_back(i);}
            } else {b.push_back(t0);}
            p0=p1;p1=a.find_first_of(",-",p0+1);
        }
    }
}
int week(int a) {
    int ori=1970,sumd=0;
    int month=a%10000/100-1,year=a/10000;
    int day=run(year)?monr[month]:mon[month];
    if(a<start/10000||a>end/10000||a%100>day) { return -1;}
    while(ori<a/10000) {sumd+=365+run(ori); ori++;}
    int i=0;
    while(i<month) {sumd+=run(year)?monr[i]:mon[i]; i++;}
    sumd+=a%100;
    return ((sumd-1)%7+4)%7;
}
bool isin(vector<int> a,int b) {
    for(int i=0; i<a.size(); i++) {if(a[i]==b) {return true;}}
    return false;
}
void fill(note a) {
    long long data=0;
    for(int k=date[0]/10000; k<=date[1]/10000; k++) {//年
        for(int i=0; i<a.num[2].size(); i++) {//日
            for(int j=0; j<a.num[3].size(); j++) {//月
                data=k*10000+a.num[3][j]*100+a.num[2][i];
                if(isin(a.num[4],week(data))) { a.num[5].push_back(data);}
            }
        }
    }
    for(int i=0; i<a.num[0].size(); i++) {//分
        for(int j=0; j<a.num[1].size(); j++) {//时
            for(int k=0; k<a.num[5].size(); k++) {//日期
                data=(long long)a.num[5][k]*10000+a.num[1][j]*100+a.num[0][i];
                if(data>=start&&data<end) { action[data].push_back(a.act);}
            }
        }
    }
}
int main() {
    mw["jan"]=1,mw["feb"]=2,mw["mar"]=3,mw["apr"]=4,mw["may"]=5,mw["jun"]=6;
    mw["jul"]=7,mw["aug"]=8,mw["sep"]=9,mw["oct"]=10,mw["nov"]=11,mw["dec"]=12;
    mw["sun"]=0,mw["mon"]=1,mw["tue"]=2,mw["wed"]=3,mw["thu"]=4,mw["fri"]=5,mw["sat"]=6;
    cin>>n>>start>>end;
    date[0]=start/10000;date[1]=end/10000;
    for(int i=0; i<n; i++) {
        for(int j=0; j<5; j++) {nt.num[j].clear();  cin>>temp;tostand(temp,nt.num[j],j);}
        cin>>nt.act;fill(nt);
    }
    map<long long,vector<string> >::iterator iter;
    for(iter = action.begin(); iter != action.end(); iter++) {
        cout<<iter->first<<" "<<iter->second[0]<<endl;
    }
    return 0;
}

问题剖析

易错点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值