CSP 201712-3 Crontab(0→85→95→100)

tag:复杂模拟 字符串 日期

题面链接

http://118.190.20.162/view.page?gpid=T66.

题意

  题目为任务的调度问题,个人感觉跟平常使用的日历中的日程计划比较类似。题目会给出多个任务以及该任务的执行时间,时间有可能是重复性的,我们需要做的就是按照时间先后输出执行的所有任务。

思路

   采取构造的方式:对于给定任务,构造所有会执行的时间,用数据结构map(时间:任务列表)进行存储,由于map本身是有序的,所以处理完所有任务后,遍历map输出即可。
  问题转化为如何构造给定任务的所有执行时间,可以先求出分钟、小时、日、月、星期的可行时间,然后进行组合,组合出yyyymmddHHMM格式的日期,其中星期由于没有显式位于日期中,因此采取对组合后的日期进行星期验证的方式保证星期的可行性。另外对于“*”即任意的情况,采取将取值范围内所有值均加入的方式进行处理,但因为构造日期可能不位于给定起始日期s,终止日期t之间、不同月份天数不同的问题可能出现非法日期(比如:0231,2月31日)等原因,所以对于构造的日期需要进一步进行检验保证其正确性。
   需要注意的几个细节如下:

1.csp 编译器比较古老,不支持一些函数如stoi、tostring的使用;(0分:编译错误)
2.月份、星期的英文缩写不区分大小写;(85分)
3.可能存在区间重合问题,比如:3,1-5 如不特殊考虑,则3就构造多次,导致出错。(95分)

源码

#include <bits/stdc  .h>#define endl '\n'using namespace std;typedef long long ll;map<string,vector<string> >mp;//时间:指令map<string,vector<string> >::iterator iter;//迭代器map<string,string> mpchar_num;//英文:数字。比如,Jan:01,Sun:00map<string,string> mp_week;//时间:周typedef struct {int year,month,day,hour,minutes;}node;node start,endt;string g_s,g_t,sminute,shour,sday,smonth,sweek,instructment;//ccf编译器不支持 my_stoi,my_to_string:进行转化int my_stoi(string s){return atoi(s.c_str());}string my_to_string(int i){char str[10];    itoa(i,str,10);    return str;}//将字符串s处理为vvoid funs_v(string s,vector<string> &v,int j_start,int j_end){v.clear();    string s1="",s2="";    char str[5];    //遍历s    for(int i=0;i<s.size();i  ){//任意符        if(s[i]=='*'){for(int j=j_start;j<=j_end;j  ){sprintf(str,"d",j);                if(find(v.begin(),v.end(),str)==v.end()) v.push_back(str);            }            break;        }        //,号        if(s[i]==','){int j=my_stoi(s1);sprintf(str,"d",j);            if(find(v.begin(),v.end(),str)==v.end()) v.push_back(str);            s1="";continue;        }        //-号        if(s[i]=='-'){//s1-s2            for(i  ;i<s.size();i  ){if(s[i]==',')break;                s2 =s[i];            }            int sj=my_stoi(s2);            for(int j=my_stoi(s1);j<=sj;j  ){sprintf(str,"d",j);                if(find(v.begin(),v.end(),str)==v.end()) v.push_back(str);            }            //s1,s2清零            s1="";s2="";continue;        }        //else:数字        s1 =s[i];    }    if(s1!="") {int j=my_stoi(s1);        sprintf(str,"d",j);        if(find(v.begin(),v.end(),str)==v.end()) v.push_back(str);    }}//将月份和周中的英文缩写处理为数字string funchar_num(string s){string ans="",s1="";    for(int i=0;i<s.size();i  ){//小写字母        if(s[i]>='a' && s[i]<='z'){s1 =s[i];continue;        }        //大写字母转为小写        if(s[i]>='A' && s[i]<='Z'){s1 =(s[i]-'A' 'a');continue;        }        if(s1!=""){ans =mpchar_num[s1];s1="";}        ans =s[i];    }    if(s1!=""){ans =mpchar_num[s1];s1="";}    return ans;}//获取某年某月的天数int month_day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};int get_day(int year,int month){//cout<<year<<" "<<month<<endl;    if(month!=2) return month_day[month];    //若是闰年    if((year%4==0 && year0!=0) || year@0==0) return month_day[month] 1;    return month_day[month];}//检查日期是否满足要求bool check(string s){//不在起止时间内    if(s<g_s || s>=g_t) return false;    //在起止时间内,判断日期合法性(月份,日)    //201711170032    //获取年、月、日    int c_year=0,c_month=0,c_day=0;    c_year=my_stoi(s.substr(0,4));    c_month=my_stoi(s.substr(4,2));    c_day=my_stoi(s.substr(6,2));    if(c_day<=get_day(c_year,c_month)) return true;    return false;}//添加指令void solve(){vector<string> vminute,vhour,vday,vmonth,vweek;    //处理分钟    funs_v(sminute,vminute,0,59);    //处理小时    funs_v(shour,vhour,0,23);    //处理日    funs_v(sday,vday,1,31);    //处理月    smonth=funchar_num(smonth);    funs_v(smonth,vmonth,1,12);    //处理周    sweek=funchar_num(sweek);    funs_v(sweek,vweek,0,6);    //cout<<sweek<<endl;    //从年到月、日、时、分构造完整时间    for(int year=start.year;year<=endt.year;year  ){for(int month=0;month<vmonth.size();month  ){for(int day=0;day<vday.size();day  ){for(int hour=0;hour<vhour.size();hour  ){for(int minute=0;minute<vminute.size();minute  ){string time="";                        time =my_to_string(year);time =vmonth[month];time =vday[day];time =vhour[hour];time =vminute[minute];                        //判断time是否符合要求  &&  是否满足该周几                        //cout<<time.substr(0,8)<<" "<<mp_week[time.substr(0,8)]<<endl;                        if(find(vweek.begin(), vweek.end(), mp_week[time.substr(0,8)]) != vweek.end() ){if(check(time)){mp[time].push_back(instructment);                                //cout<<instructment<<endl;                            }                        }                    }                }            }        }    }}//mpchar_num,mp_week的初始化void initial(){//初始化mpchar_num    string s_month[]={"jan", "feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};    string s_week[]={"sun", "mon","tue","wed","thu","fri","sat"};    for(int i=0;i<12;i  ) mpchar_num[s_month[i]]=my_to_string(i 1);    for(int i=0;i<7;i  ) mpchar_num[s_week[i]]=my_to_string(i);    //初始化mp_week    int week=4;//1970年1月1日:周四    string time="";    char str[5];    for(int year=1970;year<=2100;year  ){for(int month=1;month<=12;month  ){int all_day=get_day(year,month);            for(int day=1;day<=all_day;day  ){//构造time                time=my_to_string(year);                sprintf(str,"d",month);                time =str;                sprintf(str,"d",day);                time =str;                //计算周次                week%=7;                sprintf(str,"d",week);                mp_week[time]=str;                week  ;                //cout<<time<<"  "<<str<<endl;            }        }    }}int main() {int n;    initial();    cin>>n>>g_s>>g_t;    //字符串转数字    start.year=my_stoi(g_s.substr(0,4));start.month=my_stoi(g_s.substr(4,2));    start.day=my_stoi(g_s.substr(6,2));start.hour=my_stoi(g_s.substr(8,2));    start.minutes=my_stoi(g_s.substr(10,2));    endt.year=my_stoi(g_t.substr(0,4));endt.month=my_stoi(g_t.substr(4,2));    endt.day=my_stoi(g_t.substr(6,2));endt.hour=my_stoi(g_t.substr(8,2));    endt.minutes=my_stoi(g_t.substr(10,2));    while(n--){cin>>sminute>>shour>>sday>>smonth>>sweek>>instructment;        solve();    }    //遍历map,输出结果    for(iter=mp.begin();iter!=mp.end();iter  ){for(int i=0;i<iter->second.size();i  ){cout<<iter->first<<" "<<iter->second[i]<<'\n';        }    }    return 0;}/*3 201711170032 2017112223520 7 * * 1,3-5 get_up30 23 * * Sat,Sun go_to_bed15 12,18 * * * have_dinner201711170700 get_up201711171215 have_dinner201711171815 have_dinner201711181215 have_dinner201711181815 have_dinner201711182330 go_to_bed201711191215 have_dinner201711191815 have_dinner201711192330 go_to_bed201711200700 get_up201711201215 have_dinner201711201815 have_dinner201711211215 have_dinner201711211815 have_dinner201711220700 get_up201711221215 have_dinner201711221815 have_dinner */

来源:https://www.icode9.com/content-4-844001.html

(0)

相关推荐