Pro3
原始文件为 CPP 代码,本文是转换后的 Markdown 文件。
#include <bits/stdc++.h>
using namespace std;
const int days_sum[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
const int mon_day[] = {29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const string mon_name[] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
const string week_name[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
map<string, int> dict;
void init()
{
for(int i = 1; i < 13; ++i) dict.insert(make_pair(mon_name[i], i));
for(int i = 0; i < 7; ++i) dict.insert(make_pair(week_name[i], i));
}
// 如果是'12',返回12; 如果是'Jan',返回1
int my_stoi(string str)
{
if(isdigit(str[0])) return stoi(str);
transform(str.begin(), str.end(), str.begin(), ::toupper);
return dict[str];
}
bool is_leapyear(int year)
{
return !(year%400) || !(year%4) && (year%100);
}
bool is_day_legal(int year, int month, int day)
{
if(is_leapyear(year) && month == 2) return day < 30 && day > 0;
return day <= mon_day[month] && day > 0;
}
int query_week(int year, int month, int day)
{
int a = (year - 1970);
int days = a * 365 + (a + 1) / 4 + days_sum[month] + day;
if(month > 2 && is_leapyear(year)) days++;
return (days + 3) % 7;
}
struct Time
{
// int year, month, day, hour, min;
int save[5];
Time(){}
Time(string str)
{
save[0] = stoi(str.substr(0,4));
for(int i = 1; i < 5; ++i) save[i] = stoi(str.substr(2*i+2, 2));
}
bool operator < (const Time& other) const
{
for(int i = 0; i < 5; ++i)
{
if(save[i] != other.save[i]) return save[i] < other.save[i];
}
return false;
}
};
void deal_with_no_comma(bool* arr, int arr_size, string str)
{
int pos = str.find('-');
if(pos != -1)
{
// 处理: 12-34
int l_value = my_stoi(str.substr(0, pos));
int r_value = my_stoi(str.substr(pos + 1));
while(l_value <= r_value) { arr[l_value] = true; ++l_value; }
}else
{
// 如果没有'-', 必定为: 12
arr[my_stoi(str)] = true;
}
}
void deal_with_comma(bool* arr, int arr_size, string str)
{
if(str[0] == '*')
{
memset(arr, true, arr_size * sizeof(bool));
return;
}
while(true)
{
int pos = str.find(',');
if(pos != -1)
{
string sub = str.substr(0, pos);
deal_with_no_comma(arr, arr_size, sub);
str = str.substr(pos + 1);
}else
{
deal_with_no_comma(arr, arr_size, str);
break;
}
}
}
struct Thing
{
bool hour_arr[24], min_arr[60];
bool mon_arr[13], day_arr[32];
bool week_arr[7];
string name;
bool this_day_ok(Time& time)
{
return mon_arr[time.save[1]] && day_arr[time.save[2]]
&& week_arr[ query_week(time.save[0], time.save[1], time.save[2]) ];
}
bool this_time_ok(Time& time)
{
return this_day_ok(time) && hour_arr[time.save[3]] && min_arr[time.save[4]];
}
// 确保今天合法
bool get_next_time_this_day(int h, int m, Time& time)
{
int index = h * 60 + m;
while(++index < 24 * 60)
{
if(hour_arr[index/60] && min_arr[index%60])
{
time.save[3] = index/60; time.save[4] = index%60;
return true;
}
}
return false;
}
// 找到下一个合法的天
bool get_next_day_this_year(int year, int m, int d, Time& time)
{
int index = m * 32 + d;
while(++index < 13 * 32)
{
if(mon_arr[index/32] && day_arr[index%32])
{
if(!is_day_legal(year, index/32, index%32)) continue;
if(!week_arr[ query_week(year, index/32, index%32) ]) continue;
time.save[0] = year; time.save[1] = index/32; time.save[2] = index%32;
return true;
}
}
return false;
}
Thing(string str)
{
stringstream ss(str);
string min, hour, day, mon, week, name;
ss >> min >> hour >> day >> mon >> week >> name;
memset(hour_arr, false, sizeof(hour_arr));
memset(min_arr, false, sizeof(min_arr));
memset(mon_arr, false, sizeof(mon_arr));
memset(day_arr, false, sizeof(day_arr));
memset(week_arr, false, sizeof(week_arr));
deal_with_comma(min_arr, 60, min);
deal_with_comma(hour_arr, 13, hour);
deal_with_comma(day_arr, 32, day);
deal_with_comma(mon_arr, 13, mon);
deal_with_comma(week_arr, 7, week);
this->name = name;
}
Time find_next_time(Time begin_time)
{
Time time{};
int year = begin_time.save[0]; int month = begin_time.save[1]; int day = begin_time.save[2];
int hour = begin_time.save[3]; int minute = begin_time.save[4];
for(int i = 0; i < 3; ++i) time.save[i] = begin_time.save[i];
if( !this_day_ok(begin_time) || !get_next_time_this_day(hour, minute, time) )
{
if( !get_next_day_this_year(year, month, day, time) )
{
while(!get_next_day_this_year(++year, 1, 0, time));
}
get_next_time_this_day(0, -1, time);
}
return time;
}
};
struct HeapNode
{
int index; Time time;
bool operator < (const HeapNode& other) const
{
if(time < other.time) return true;
if(other.time < time) return false;
return index < other.index;
}
};
int main()
{
// freopen("in.txt", "r", stdin);
init();
int n; string str01, str02;
cin >> n >> str01 >> str02;
Time hi(str01), lo(str02);
vector<HeapNode> Q;
vector<string> thing_name;
string str03; cin.get();
for(int i = 0; i < n; ++i)
{
getline(cin, str03); Thing cur(str03);
thing_name.push_back(cur.name);
Time this_time = (cur.this_time_ok(hi)) ? hi : cur.find_next_time(hi);
while(this_time < lo) {
Q.push_back({i, this_time});
this_time = cur.find_next_time(this_time);
}
}
sort(Q.begin(), Q.end());
for(auto x : Q)
{
Time time = x.time;
cout << time.save[0];
for(int i = 1; i < 5; ++i) cout << setw(2) << setfill('0') << time.save[i];
cout << " " << thing_name[x.index] << endl;
}
return 0;
}