• 日期相关整理


    3214. 节日

    有一类节日的日期并不是固定的,而是以“a 月的第 b 个星期 c ”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。

    现在,给你 a,b,c 和 y1,y2,希望你输出从公元 y1 年到公元 y2 年间的每年的 a 月的第 b 个星期 c 的日期。

    提示:关于闰年的规则:年份是 400 的整数倍时是闰年,否则年份是 4 的倍数并且不是 100 的倍数时是闰年,其他年份都不是闰年。

    例如 1900 年就不是闰年,而 2000 年是闰年。

    为了方便你推算,已知 1850 年 1 月 1 日是星期二。

    输入格式

    输入包含恰好一行,有五个整数 a,b,c,y1,y2。

    其中 c=1,2,……,6,7 分别表示星期一、二、……、六、日。

    输出格式

    对于 y1 和 y2 之间的每一个年份,包括 y1 和 y2,按照年份从小到大的顺序输出一行。

    如果该年的 a 月第 b 个星期 c 确实存在,则以 yyyy/mm/dd 的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠 / 分隔,位数不足时前补零。

    如果该年的 a 月第 b 个星期 c 并不存在,则输出 none

    1. #include
    2. using namespace std;
    3. int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    4. //将月份与天数对应
    5. int is_leap(int y) //如果当前年为闰年返回1,否则返回0
    6. {
    7. if (y % 400 == 0 || y % 4 == 0 && y % 100) return 1;
    8. return 0;
    9. }
    10. int get_days(int y, int m) //返回当前月共有多少天
    11. {
    12. if (m == 2) return months[m] + is_leap(y);
    13. return months[m];
    14. }
    15. int main()
    16. {
    17. int a, b, c, y1, y2;
    18. cin >> a >> b >> c >> y1 >> y2;
    19. int days = 0; //记录当前天距离1850.1.1有多少天
    20. for (int y = 1850; y <= y2; y ++)
    21. for (int m = 1; m <= 12; m ++)
    22. {
    23. if (y >= y1 && m == a) //到所求月份
    24. {
    25. int w = (1 + days) % 7, cnt = 0; //w为当前月第一天的星期几
    26. //注1850.1.1是星期二,所以加1
    27. for (int d = 1; d <= get_days(y, m); d ++)
    28. {
    29. if (w == c - 1) //0,1,2,,,6分别表示星期1到7
    30. {
    31. cnt ++;
    32. if (cnt == b)
    33. {
    34. printf("%04d/%02d/%02d\n", y, m, d);
    35. break;
    36. }
    37. }
    38. w = (w + 1) % 7;
    39. }
    40. if (cnt < b) puts("none");
    41. }
    42. days += get_days(y, m);
    43. }
    44. return 0;
    45. }

    3254. Crontab

    Cron (源自希腊语 χρόνοςχρόνος,意思是时间〉是类 Unix 系统下基于时间的任务调度器,用于在固定的时间运行指定的任务(多为系统管理和维护的任务)。

    Cron 适合于周期性重复调度的任务,通过crontab文件来描述调度任务的配置。

    Crontab文件由若干行组成,每行是一条配置信息,格式如下:

    <minutes> <hours> <day of month> <month> <day of week> <command>
    

    表示在满足前 5 项所指定的时间来运行第 6 项  所描述的命令。

    前 55 项用于描述时间,含义和取值范围如下:

    •  是分钟数,取值范围是 0−59;
    •  是小时数,取值范围是 0−23;
    •  是月份中的天数,取值范围是 1−31;
    •  是月份,取值范围是 1−12,或 Jan - Dec ;
    •  是星期几,取值范围是 0−6,或 Sun - Sat

    对于前 5 项,除了可以直接给出数字或者英文缩写(不区分大小写)外,还可以出现星号 *(表示任何取值)、逗号 , (表示多个不同的取值)或减号 - (表示一段连续的取值范围)。

    星号只能单独出现,减号和逗号可以配合出现。

    Cron 每分钟检查一次系统时间,当系统时间同时满足这 5 项要求时,cron 将执行对应的命令。

    给出一个时间段,以及一个 crontab 文件,请你编程输出在这段时间内的任务调度执行情况。

    输入格式

    输入第一行有 33 个整数 n、s、t,用空格分隔。n 表示接下来有 n 行,描述一个 crontab 文件。s 和 t 分别为系统运行的开始时间(包含)和结束时间(不包含),格式为 yyyymmddHHMM(年、月、日、小时、分钟)。

    接下来有 n 行,每行是一条 crontab 配置信息,相邻两项之间用一个空格分隔。

    输出格式

    输出有若干行,每行表示一个任务调度,由两部分构成︰第一部分是任务调度的时间,格式同样为 yyyymmddHHMM,第二部分是调度执行的命令。

    两部分之间用一个空格分隔。

    按照时间先后顺序输出。

    如果同一时刻有多条命令满足调度条件,则按照输入给出的顺序输出

    数据范围

    输入数据约定:

    • 1≤n≤20,s≤t
    • 输入数据中给出的时间均在 1970-01-01 00:00 到 2099-12-31 23:59 之间。
    • 输入中给出的命令只包含大小写字母、数字和下划线 _,不包含空格或其他符号。
    • 保证输入中描述时间的部分都是合法的。对于减号描述的时间范围 x−y,一定满足 x≤y。英文缩写的拼写保证是正确的。英文缩写和数值可以混合使用。分钟数和小时数可以有前导 0,也可以没有(例如,00 和 0 都是合法的输入),其他部分不会出现前导 0。
    • 输入的每行不超过 100 个字符。
    • 保证输出内容不超过 10000 行。
    • 提示:1970 年 1 月 1 日是星期四。

    输入数据特征(√ 表示可以出现,× 表示不会出现)∶

    QQ截图20210208111813.png

    附:月份与星期的英文缩写对照表:

    QQ截图20210208111913.png

    QQ截图20210208111937.png

    输入样例:

    1. 3 201711170032 201711222352
    2. 0 7 * * 1,3-5 get_up
    3. 30 23 * * Sat,Sun go_to_bed
    4. 15 12,18 * * * have_dinner

    输出样例:

    1. 201711170700 get_up
    2. 201711171215 have_dinner
    3. 201711171815 have_dinner
    4. 201711181215 have_dinner
    5. 201711181815 have_dinner
    6. 201711182330 go_to_bed
    7. 201711191215 have_dinner
    8. 201711191815 have_dinner
    9. 201711192330 go_to_bed
    10. 201711200700 get_up
    11. 201711201215 have_dinner
    12. 201711201815 have_dinner
    13. 201711211215 have_dinner
    14. 201711211815 have_dinner
    15. 201711220700 get_up
    16. 201711221215 have_dinner
    17. 201711221815 have_dinner

    样例解释

    样例输入给出了 3 条 cron 配置信息,系统运行的开始时间是 2017-11-17 00:32(包含),结束时间为 2017-11-22 23:52(不包含)。

    每条配置信息的含义如下:
    1.在星期一、三、四、五的 7 点整运行 get_up 命令。
    2.在星期六、星期天的 23 点 30 分运行 go_to_bed 命令。
    3.在每天的 12 点 15 分和 18 点 15 分运行 have_dinner 命令。

    1. #include
    2. using namespace std;
    3. int n;
    4. int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    5. struct Timer
    6. {
    7. int year, month, day, hour, minute, week;
    8. Timer(string str)
    9. {
    10. sscanf(str.c_str(), "%04d%02d%02d%02d%02d", &year, &month, &day, &hour, &minute);
    11. //c_str() 将const string*类型 转化为const char*类型
    12. }
    13. bool operator< (const Timer &t)const //set
    14. {
    15. if (year != t.year) return year < t.year;
    16. if (month != t.month) return month < t.month;
    17. if (day != t.day) return day < t.day;
    18. if (hour != t.hour) return hour < t.hour;
    19. return minute < t.minute;
    20. }
    21. int is_leap()
    22. {
    23. if (year % 400 == 0 || (year % 100 && year % 4 == 0)) return 1;
    24. return 0;
    25. }
    26. int get_days()
    27. {
    28. if (month == 2) return months[2] + is_leap();
    29. return months[month];
    30. }
    31. void next()
    32. {
    33. if (++ minute == 60)
    34. {
    35. minute = 0;
    36. if (++ hour == 24)
    37. {
    38. week = (week + 1) % 7;
    39. hour = 0;
    40. if (++ day > get_days())
    41. {
    42. day = 1;
    43. if (++ month == 13)
    44. {
    45. month = 1;
    46. year ++;
    47. }
    48. }
    49. }
    50. }
    51. }
    52. string to_string()
    53. {
    54. char str[20];
    55. sprintf(str, "%04d%02d%02d%02d%02d", year, month, day, hour, minute);
    56. return str;
    57. }
    58. };
    59. struct Task
    60. {
    61. bool minutes[60], hours[24], day_of_month[32], month[13], day_of_week[7];
    62. string name;
    63. bool check(Timer &t)
    64. {
    65. return minutes[t.minute] && hours[t.hour] && day_of_month[t.day] &&
    66. month[t.month] && day_of_week[t.week];
    67. }
    68. }task[20];
    69. unordered_mapint> nums;
    70. void init() //将月份及星期的英文表达与其值对应起来
    71. {
    72. //注意 0-6分别为星期天到星期六
    73. string key[] = {
    74. "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec",
    75. "sun", "mon", "tue", "wed", "thu", "fri", "sat"
    76. };
    77. int value[] = {
    78. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
    79. 0, 1, 2, 3, 4, 5, 6
    80. };
    81. for (int i = 0; i < 19; i ++)
    82. nums[key[i]] = value[i];
    83. }
    84. int get(string str) //将其字符串转换为它所表达的数值
    85. {
    86. if (str[0] <= '9' && str[0] >= '0') return stoi(str);
    87. string s;
    88. for (auto c: str) s += tolower(c);
    89. return nums[s];
    90. }
    91. void work(string str, bool st[], int len) //标记当前任务数组是否在范围内
    92. {
    93. if (str == "*")
    94. {
    95. for (int i = 0; i < len; i ++) st[i] = true;
    96. }
    97. else
    98. {
    99. for (int i = 0; i < str.size(); i ++)
    100. {
    101. int j = i + 1;
    102. while (j < str.size() && str[j] != ',') j ++;
    103. string s = str.substr(i, j - i);
    104. i = j;
    105. int k = s.find('-');
    106. if (k != -1)
    107. {
    108. int l = get(s.substr(0, k)), r = get(s.substr(k + 1));
    109. for (int u = l; u <= r; u ++) st[u] = true;
    110. }
    111. else st[get(s)] = true;
    112. }
    113. }
    114. }
    115. int main()
    116. {
    117. init();
    118. string st, ed;
    119. cin >> n >> st >> ed;
    120. for (int i = 0; i < n; i ++)
    121. {
    122. string minutes, hours, day_of_month, month, day_of_week, name;
    123. cin >> minutes >> hours >> day_of_month >> month >> day_of_week >> name;
    124. work(minutes, task[i].minutes, 60);
    125. work(hours, task[i].hours, 24);
    126. work(day_of_month, task[i].day_of_month, 32);
    127. work(month, task[i].month, 13);
    128. work(day_of_week, task[i].day_of_week, 7);
    129. task[i].name = name;
    130. }
    131. Timer t("197001010000"), S(st), E(ed); //t为题目给出的日期,当前为星期四
    132. t.week = 4;
    133. while (t < E)
    134. {
    135. if (!(t < S)) //注意只重载了小于号 所以>=用!<表示
    136. {
    137. for (int i = 0; i < n; i ++)
    138. if (task[i].check(t))
    139. cout << t.to_string() << " " << task[i].name << endl;
    140. }
    141. t.next(); //下一天
    142. }
    143. return 0;
    144. }

  • 相关阅读:
    C++算法:给表达式添加运算符
    【Linux】进程控制
    vue前端密码加密,springboot后端密码解密
    万字长文带你了解 CloudOps 自动化运维的奥秘,助力云上业务高效稳定运行
    全球创业浪潮:跨境电商的创新时代
    Python全栈开发【基础-03】编程语言的分类
    PyTorch搭建CNN实现视频动作分类任务
    这几个必备的vscode插件,你安装了几个
    Windows下搭建GTK3开发环境
    以往我们认识的产业互联网,只是以消费互联网的替代者的身份出现
  • 原文地址:https://blog.csdn.net/Zo_ee/article/details/134471077