CCF 201712-3 Crontab
本地AC,CCF编译失败。
通过对每条任务进行处理,将可能的月,日处理出来,并且比对对应星期是否符合要求。再对时分进行处理,判断整体时间在所给区域内。
思路借鉴自https://blog.csdn.net/gl486546/article/details/79057666
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
char vMon[][4] = { "","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec" };
char vWek[][4] = { "sun","mon","tue","wed","thu","fri","sat" };
int monthArray[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
map<string, int> mMon, mWeek;//map string to int
map<string, vector<string>> mrt;//time -> commands //results
void bulidMonAndWeekMap() {
for (int i = 1; i <= 12; i++) mMon[vMon[i]] = i;
for (int i = 0; i <= 6; i++) mWeek[vWek[i]] = i;//
}
void standlize(string & s) {
for (int i = 0; i<s.size(); i++) {
s[i] = tolower(s[i]);
}
}
bool isLeapYear(int y) {
return (y % 400 == 0) || (y % 4 == 0 && y % 100);
}
int getDayOfWeek(int year, int month, int dayOfMonth) {
//calculate days from 1970-01-01,of which the dayOfWeek is 4.
int count = 0;
for (int i = 1970; i < year; i++) {
count += (isLeapYear(i) ? 366 : 365);
}
monthArray[2] = isLeapYear(year) ? 29 : 28;
for (int i = 1; i < month; i++)
count += monthArray[i];
count += dayOfMonth-1;
return (count + 4) % 7;
}
int stoi_my(const string & a) {
int r=0;
for (int i = 0; i < a.size(); i++) {
r = r * 10 + a[i] - '0';
}
return r;
}
string itos(const int & i) {
char s[30];
sprintf(s, "%d", i);
return string(s);
}
vector<string> splitStringAndBulidVector(string& str, int TAG = 0) {//TAG=0(other),1(month),2(dayOfWeek)
//transform string to vector of the num
// 1-12 or 1,2.Split this by ',' and then split num with '-'.
vector<string> vstring;
str += ",";
size_t found = str.find(',');
while (found = str.find(','),found != string::npos) {
string x = str.substr(0, found);
str = str.substr(found + 1, str.size() - found - 1);
size_t found2 = x.find('-');
if (found2 == string::npos) {// one number or string
if (TAG == 1 && isalpha(x[0])) x = itos(mMon[x]);
if (TAG == 2 && isalpha(x[0])) x = itos(mWeek[x]);
if (x.size() == 1) {
x = "0" + x;
}
vstring.push_back(x);
}
else {//1-2 or jan-feb or mon-fri
string a = x.substr(0, found2);
string b = x.substr(found2 + 1, x.size() - found2 - 1);
int l = 0, r = 0;
if (TAG == 0) { l = stoi_my(a), r = stoi_my(b); }
else if (TAG == 1) {//month
l = (isalpha(a[0])) ? mMon[a] : stoi_my(a);
r = (isalpha(b[0])) ? mMon[b] : stoi_my(b);
}
else {
l = (isalpha(a[0])) ? mWeek[a] : stoi_my(a);
r = (isalpha(b[0])) ? mWeek[b] : stoi_my(b);
}
while (l <= r) {
string lstr = l<10?"0"+itos(l):itos(l);
vstring.push_back(lstr);
l++;
}
}
}
return vstring;
}
int main()
{
freopen("in.txt", "r", stdin);
//get inputs
bulidMonAndWeekMap();
int n;
string st, et;
cin >> n >> st >> et;
string syy = st.substr(0, 4), smm = st.substr(4, 2), sdd = st.substr(6, 2), sHH = st.substr(8, 2), sMM = st.substr(10, 2);
string eyy = et.substr(0, 4), emm = et.substr(4, 2), edd = et.substr(6, 2), eHH = et.substr(8, 2), eMM = et.substr(10, 2);
int syyInt = stoi_my(syy), eyyInt = stoi_my(eyy);
vector<string> vminute, vhour, vdayOfMonth, vmonth, vdayOfWeek;
while (n--) {
string minutes, hours, dayOfMonth, month, dayOfWeek, command;
cin >> minutes >> hours >> dayOfMonth >> month >> dayOfWeek >> command;
standlize(month); standlize(dayOfWeek);//Transform to lower case
if (minutes == "*")minutes = "1-59";
vminute = splitStringAndBulidVector(minutes);
if (hours == "*")hours = "0-23";
vhour = splitStringAndBulidVector(hours);
if (dayOfMonth == "*")dayOfMonth = "1-31";
vdayOfMonth = splitStringAndBulidVector(dayOfMonth);
if (month == "*")month = "1-12";
vmonth = splitStringAndBulidVector(month, 1);
if (dayOfWeek == "*")dayOfWeek = "0-6";
vdayOfWeek = splitStringAndBulidVector(dayOfWeek, 2);
int dayOfWeekArray[7] = { 0 };// for quick querying
fill(dayOfWeekArray, dayOfWeekArray + 7, 0);
for (int i = 0; i<vdayOfWeek.size(); i++)
dayOfWeekArray[stoi_my(vdayOfWeek[i])] = 1;
int curyear = syyInt;//Start from syyInt.Do this for each command;
while (curyear <= eyyInt) {
monthArray[2] = isLeapYear(curyear) ? 29 : 28;
string year = itos(curyear);
//iterator month
for (vector<string>::iterator mi = vmonth.begin(); mi<vmonth.end(); mi++) {
for (vector<string>::iterator di = vdayOfMonth.begin(); di<vdayOfMonth.end(); di++) {
int dayOfWeekInt = getDayOfWeek(curyear, stoi_my(*mi), stoi_my(*di));
//check whether dayOfWeek is right and dayOfMonth less than Max
if (!dayOfWeekArray[dayOfWeekInt] || (stoi_my(*di))>monthArray[stoi_my(*mi)])
continue;
//iterator hours and minutes
for (vector<string>::iterator hi = vhour.begin(); hi<vhour.end(); hi++) {
for (vector<string>::iterator mini = vminute.begin(); mini<vminute.end(); mini++) {
string datetime = year + *mi + *di + *hi + *mini;
if (datetime >= st && datetime <= et)
mrt[datetime].push_back(command);//push command into the vector of this time
}
}
}
}
curyear++;
}
}
//iterator results
for (map<string, vector<string>>::iterator it = mrt.begin(); it != mrt.end(); it++) {
for (vector<string>::iterator rit = it->second.begin(); rit<it->second.end(); rit++) {
cout << it->first + " " + *rit << endl;
}
}
return 0;
}