思路:
这题若想不超时,就必须把所有可能的指令转换成日期,再结合星期限制舍去一些不合适的情况,最终按序输出即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string cron[25][6];
int range[]={60,24,31,12,7};
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
string week[]={"sun","mon","tue","wed","thu","fri","sat"};
string month[]={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
map<ll,string>command;
int syear,eyear;
int getweek(int year,int month,int day){
days[2]=28;
if(year%4==0)days[2]++;
if(day>days[month])return -1;
int sum=4;
int cnt=(year-1-1968)/4;//闰年数
sum=4+365*(year-1970)+cnt;
for(int i=1;i<month;i++)sum+=days[i];
sum=(sum+day-1)%7;
return sum;
}
int tonum(string str){
if(isalpha(str[0])){
for(int i=0;i<12;i++){
if(str==month[i])return i+1;
if(i<7&&str==week[i])return i;
}
}
else {
int num=0;
for(int i=0;i<str.size();i++){
num=num*10+str[i]-'0';
}
return num;
}
}
void deal(string str,set<int>&nums){
int idex=0;
if((idex=str.find('-'))!=-1){
str[idex]=' ';
stringstream ss;
string s;
ss<<str;
ss>>s;
int beg=tonum(s);
ss>>s;
int end=tonum(s);
for(int i=beg;i<=end;i++){
nums.insert(i);
}
}
else {
nums.insert(tonum(str));
}
}
void crontonum(string &str,int j,set<int>&nums){
if(str=="*"){
for(int k=0;k<range[j];k++){
if(j==2||j==3)nums.insert(k+1);
else nums.insert(k);
}
return ;
}
int idex;
while((idex=str.find(','))!=-1){
str[idex]=' ';
}
stringstream ss;
string s;
ss<<str;
while(ss>>s){
deal(s,nums);
}
}
void numtodate(vector<vector<ll>>&num,set<int> &nums,int j,ll mul){
if(j==0){
for(auto it: nums) num[j].push_back(it);
}
else if(j<4){
for(auto it:nums){
for(auto id:num[j-1]){
num[j].push_back(it*mul+id);
}
}
}
else{
int mark[7]={0};
for(auto it:nums)mark[it]=1;
for(int year=syear;year<=eyear;year++){
for(int i=0;i<num[j-1].size();i++){
int month=num[j-1][i]/1000000;
int day=num[j-1][i]/10000%100;
int temp=getweek(year,month,day);
if(temp!=-1&&mark[temp]){
num[j].push_back(year*mul+num[j-1][i]);
}
}
}
}
}
int main(){
int n;
ll s,t;
//输入
cin>>n>>s>>t;
syear=s/100000000;
eyear=t/100000000;
for(int i=0;i<n;i++){
for(int j=0;j<6;j++){
cin>>cron[i][j];
if(j==3||j==4){
for(auto &it: cron[i][j]){
it=tolower(it);
}
}
}
}
//处理
for(int i=0;i<n;i++){
vector<vector<ll>>num(5,vector<ll>());
ll mul=1;
for(int j=0;j<5;j++){
set<int> nums;
crontonum(cron[i][j],j,nums);
numtodate(num,nums,j,mul);
mul*=100;
}
for(int j=0;j<num[4].size();j++){
if(num[4][j]>=s&&num[4][j]<t){
command.insert(make_pair(num[4][j],cron[i][5]));
}
}
}
//输出
for(auto it:command){
cout<<it.first<<' '<<it.second<<endl;
}
return 0;
}
样例
3 201711170032 201711222352
0 7 * * 1,3-5 get_up
30 23 * * Sat,Sun go_to_bed
15 12,18 * * * have_dinner