ccf201712-3 crontab
程序员文章站
2022-07-07 18:56:29
...
ccf201712-3 crontab
我嬲你麻麻别,我这个小菜鸡是拜倒在这了,我写了感觉得8小时了(一共写3天一天写一会),最后还只得了80,原因我找了,暴力法超时了。这题暴力法不处理英文字符得65,处理大小写得80,然后就我水平有限,分就这样了,改不了了,我发现自己和那些大佬的代码还是差好多,,比如人家用longlong存数,用10^x次方代表月日等,我只会用字符串存,人家用map,我只会数组、。。。
下面是题目和代码,代码要说有优点,就是简单易懂了吧
#include<bits/stdc++.h>
using namespace std;
const string str1[19]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
const string str2[19]={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec","sun","mon","tue","wed","thu","fri","sat"};
int data[20][6][61]={0};
struct bound{
int low;
int high;
};
int runnian(int year)
{
if(year%4==0&&year%100!=0||year%400==0)
return 1;
else
return 0;
}
vector<string> split(string str,char flag)
{
vector<string> vs;
istringstream iss(str);
while(getline(iss,str,flag))
vs.push_back(str);
return vs;
}
int dayue(int mouth)
{
if(mouth==1||mouth==3||mouth==5||mouth==7||mouth==8||mouth==10||mouth==12)
return 1;
else if(mouth==2)
return -1;
else
return 0;
}
int xingqi(int year,int mouth,int day)
{
int sumday=0;
int xq=0;
int syear=0;
int smouth=1;
for(syear=1970;syear<year;syear++)
{
if(runnian(syear))
sumday=sumday+366;
else
sumday=sumday+365;
}
for(smouth=1;smouth<mouth;smouth++)
{
if(runnian(syear)&&smouth==2)
sumday=sumday+29;
else if((!runnian(syear))&&smouth==2)
sumday=sumday+28;
else if(dayue(smouth)==1)
sumday+=31;
else
sumday+=30;
}
sumday+=day-1;
sumday+=4;
xq=sumday%7;
return xq;
}
bound _to(string str)
{
bound bd;
stringstream s3;
int pos=str.find('-');
string s1=str.substr(0,pos);
string s2=str.substr(pos+1,str.length()-pos-1);
bd.low=atoi(s1.c_str());
bd.high=atoi(s2.c_str());
return bd;
}
int main()
{
int n;
cin>>n;
string start,end;
cin>>start>>end;
int s_year,s_mouth,s_day,s_hour,s_min;
int e_year,e_mouth,e_day,e_hour,e_min;
s_year=atoi(start.substr(0,4).c_str());
s_mouth=atoi(start.substr(4,2).c_str());
s_day=atoi(start.substr(6,2).c_str());
s_hour=atoi(start.substr(8,2).c_str());
s_min=atoi(start.substr(10,2).c_str());
e_year=atoi(end.substr(0,4).c_str());
e_mouth=atoi(end.substr(4,2).c_str());
e_day=atoi(end.substr(6,2).c_str());
e_hour=atoi(end.substr(8,2).c_str());
e_min=atoi(end.substr(10,2).c_str());
string op[21];
getchar();
for(int i=0;i<n;i++)
{
getline(cin,op[i]);
vector<string> vs;
vs=split(op[i],' ');//vs以空格分段
op[i]=vs[5].c_str();//op重写,变为commmand
for(int j=0;j<5;j++)
{
for(int k=0;k<vs[j].size();k++)
{
if(vs[j][k]>='A'&&vs[j][k]<='Z')
vs[j][k]+=32;
}
for(int k=0;k<19;k++)//英文日期替换整数字符串
{
while(vs[j].find(str2[k])!=vs[j].npos)
{
int pos1=vs[j].find(str2[k]);
ostringstream os;
if(k>11){
os<<k-12;
vs[j].replace(pos1,3,os.str());
}
else{
os<<k+1;
vs[j].replace(pos1,3,os.str());
}
}
}
// cout<<vs[j]<<' ';
if(vs[j]=="*")//*就全赋值
{
switch(j)
{
case 0:
for(int k=0;k<60;k++)
data[i][j][k]=1;
break;
case 1:
for(int k=0;k<24;k++)
data[i][j][k]=1;
break;
case 2:
for(int k=1;k<32;k++)
data[i][j][k]=1;
break;
case 3:
for(int k=1;k<13;k++)
data[i][j][k]=1;
break;
case 4:
for(int k=0;k<7;k++)
data[i][j][k]=1;
break;
default:
;
}
}
else
{
vector<string> vs1;
vs1=split(vs[j],',');//vs1以逗号分段
for(int k=0;k<vs1.size();k++)
{
if(vs1[k].find('-')!=vs1[k].npos)
{
bound bd=_to(vs1[k]);
for(int m=bd.low;m<=bd.high;m++)
{
data[i][j][m]=1;
}
vs1.erase(vs1.begin()+k);
}
}
for(int k=0;k<vs1.size();k++)
{
data[i][j][atoi(vs1[k].c_str())]=1;
}
}
}
}
int year=s_year;int mouth=s_mouth;int day=s_day;int hour=s_hour;int min=s_min;
while(year!=e_year||mouth!=e_mouth||day!=e_day||hour!=e_hour||min!=e_min)//遍历从开始到结束的每一分钟
{
int week=xingqi(year,mouth,day);//年月日转星期
for(int i=0;i<n;i++)
{
if(data[i][0][min]==1&&data[i][1][hour]==1&&data[i][2][day]==1&&data[i][3][mouth]==1&&data[i][4][week]==1)//0表示分钟,1:小时,2:每月天数,3:月份,4:星期数
{
printf("%04d%02d%02d%02d%02d",year,mouth,day,hour,min);
cout<<' '<<op[i]<<endl;
}
}
min++;
if(min>59)
{
hour++;
min=0;
}
if(hour>23)
{
day++;
hour=0;
}
if(day>29&&mouth==2&&runnian(year)||day>28&&mouth==2&&!runnian(year)||day>31&&dayue(mouth)||day>30&&(dayue(mouth)==0))
{
mouth++;
day=1;
}
if(mouth>12)
{
mouth=1;
year++;
}
}
}