问题描述

试题编号: 201712-3
试题名称: Crontab
时间限制: 10.0s
内存限制: 256.0MB
问题描述:
CCF 201712-3 Crontab
CCF 201712-3 CrontabCCF 201712-3 Crontab
CCF 201712-3 Crontab
样例输入
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

 

  1 #include<bits/stdc++.h>
  2 #define pb emplace_back
  3 using namespace std;
  4 typedef vector<string> vecstr;
  5 const char Month[14][4]={"","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
  6 const char Week[8][4]={"sun","mon","tue","wed","thu","fri","sat"};
  7 int n,cnt,Daysofmon[14]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  8 map<string,int> weekmap,monthmap; map<string,vecstr > all;
  9 string stime,etime;
 10 inline void stdit(string &s){transform(s.begin(),s.end(),s.begin(),::tolower);}
 11 //字符串中的字母全部变为小写字母 
 12 inline string i2s(int a){//将给定的整数变为字符串
 13     ostringstream o;o<<a;
 14     return o.str();
 15 }
 16 inline int s2i(const string &s){//将给定的字符串变为整数
 17     int num;
 18     istringstream i(s);i>>num;
 19     return num;
 20 }
 21 inline bool leap(int year){
 22     return (year%400==0)||(year%100!=0&&year%4==0);
 23 }
 24 string getweek(const string &cyyyy,const string &cmm,const string &cdd){
 25     //根据1970-01-01是星期四开始推算yyyymmdd为星期几 
 26     int year=s2i(cyyyy),mm=s2i(cmm),dd=s2i(cdd);
 27     int sum=0;
 28     for(int i=1970;i<year;i++) sum+=leap(i)?366:365;
 29     Daysofmon[2]=leap(year)?29:28;
 30     for(int i=1;i<mm;i++)  sum+=Daysofmon[i];
 31     sum+=dd-1;
 32     return i2s((4+sum)%7);
 33 }
 34 vecstr setvec(string &str,int type=0){
 35 //把时间(分钟、小时、年、月、日、周)分割成数组化的标准形式 
 36 //    type一共三种,当key为1是,表示建立week,当key为2时,表示建立month
 37 //  其他的为0
 38     vecstr rev;
 39     str+=',';
 40     string curs,arry[2];int brd[2];
 41     for(int ix,fx;~(ix=str.find(','));){
 42         curs=str.substr(0,ix);
 43         str=str.substr(ix+1);
 44         fx=curs.find('-');
 45         if(~fx){//连续时间段 
 46             arry[0]=curs.substr(0,fx);
 47             arry[1]=curs.substr(fx+1);
 48             for(int b=0;b<2;b++){
 49                 string &ss=arry[b];
 50                 if(isalpha(ss[0])){
 51                     brd[b]=(type==1)?weekmap[ss]:monthmap[ss];
 52                 }
 53                 else{
 54                     brd[b]=s2i(ss);
 55                 } 
 56             }
 57             for(int i=brd[0];i<=brd[1];i++) rev.pb(i2s(i));
 58         }
 59         else{//单个时间 
 60             if(isalpha(curs[0])){
 61                 if(type==1) rev.pb(i2s(weekmap[curs]));
 62                 else rev.pb(i2s(monthmap[curs]));
 63             }
 64             else{
 65                 rev.pb(curs);
 66             }
 67         }
 68     }
 69     return rev;
 70 }
 71 int main(){
 72     cin>>n;
 73     cin>>stime>>etime;
 74     int syear=s2i(stime.substr(0,4)),eyear=s2i(etime.substr(0,4));
 75     for(int i=0;i<7;i++) weekmap[Week[i]]=i;
 76     for(int i=1;i<=12;i++) monthmap[Month[i]]=i;
 77     for(string minutes,hours,d_of_m,month,d_of_w,command;n--;){
 78         cin>>minutes>>hours>>d_of_m>>month>>d_of_w>>command;
 79         stdit(month);
 80         stdit(d_of_w);
 81         if(minutes=="*") minutes="0-59";
 82         vecstr vminutes=setvec(minutes);
 83         if(hours=="*") hours="0-23";
 84         vecstr vhours=setvec(hours);
 85         if(d_of_m=="*") d_of_m="1-31";
 86         vecstr vd_of_m=setvec(d_of_m);
 87         if(month=="*") month="1-12";
 88         vecstr vmonth=setvec(month,2);
 89         if(d_of_w=="*") d_of_w="0-6";
 90         vecstr vd_of_w=setvec(d_of_w,1);
 91         set<string> one(vd_of_w.begin(),vd_of_w.end());
 92         //对前面的四项进行遍历,然后根据星期几和时间的合法性进行取舍
 93         for(int nowyear=syear;nowyear<=eyear;nowyear++){
 94             Daysofmon[2]=leap(nowyear)?29:28;
 95             for(auto &i:vmonth){
 96                 for(auto &j:vd_of_m){
 97                     string cyear=i2s(nowyear);
 98                     if(Daysofmon[s2i(i)]<s2i(j)||one.count(getweek(cyear,i,j))==0) continue;
 99                     // 判断日期是否合法:1、当前年月日是否存在 2、当前年月日星期几 
100                     for(auto &k:vhours){
101                         for(auto &m:vminutes){
102                             string ss=cyear
103                                 +(i.size()>1?i:"0"+i) 
104                                 +(j.size()>1?j:"0"+j) 
105                                 +(k.size()>1?k:"0"+k) 
106                                 +(m.size()>1?m:"0"+m); 
107                             if(ss>=stime&&ss<etime) all[ss].pb(command);
108                             //注意 [ ) 
109                         }
110                     }
111                 }
112             }
113         }
114     }
115     for(auto &i:all){
116         set<string> haxi;//不判重 95分,不明白~~ 
117         for(auto &k:i.second){
118             if(haxi.count(k)) continue;
119             cout<<i.first<<" "<<k<<"\n";
120             haxi.insert(k);
121         }
122     }
123     return 0;
124 }
点击这里解读本代码

相关文章:

  • 2021-04-06
  • 2022-12-23
  • 2021-11-13
  • 2022-12-23
  • 2021-05-13
  • 2021-04-20
  • 2022-02-18
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-07-14
  • 2022-02-11
  • 2021-12-09
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案