当前位置:   article > 正文

【蓝桥杯 C++】 蓝桥杯真题 回文日期 (有点暴力 找到一个蓝桥杯OJ的数据漏洞)_c++蓝桥杯回文日期

c++蓝桥杯回文日期

题目描述

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。

有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。

也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。

给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。

输入描述

输入包含一个八位整数 N,表示日期(不一定是回文日)

对于所有评测用例,10000101 \leq N \leq 8999123110000101≤N≤89991231,保证 NN 是一个合法日期的 8 位数表示。

输出描述

输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。

输入输出样例

示例

输入

20200202

输出

  1. 20211202
  2. 21211212

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

读题:

这一道题放在比较简单题的一栏,但是只有三分之二的通过率,这道题看上去很唬人,要找出输入日期的下一个回文日期和下一个 ABABBABA 型的回文日期,实际把问题拆分就很好做了。

做题之前要知道以下五点:

1.不是年年都有回文日期的。

2.某一年如果有回文日也就只能有一个回文日。(因为回文日期受年份影响)

3.某月某日可以用确定的年得到。

4.ababbaba只需判断年份为abab且可生成合法日期即可。

5.输入不都是回文日期。

解题思路:

通过读题我们就可知道,解题得关键就是找到对应的年份。题目给出了一个输入的范围那么我们就可以通过给出范围的前4位数作为遍历年份的范围。

对于遍历的年份我们应该做出如下判断:

判断1.判断生成的日期是否合理。

判断2.在生成日期合理的前提下判断是否是ababbaba型的年份。

注意:判断生成日期是否合理是要考虑闰年的判断。

如果通过了判断一那么他就是我们要找的下一个回文日期;如果通过了判断二那么就是哦我们要找的下一个ababbaba型回文日期。

细节部分:

思路已经找到了,代码实现起来也比较容易,但是仍然通过不了,有以下几个细节:

1.如果输入的样例是一个回文日期那么找下一个有回文日的年;如果输入样例不是回文日期,但是所在年份有回文,需要判断这一年的回文日期在输入之前还是之后,如果在之前丢掉,如果在之后,就是要找的下一个回文日期(其实这一条蓝桥杯的OJ会判不出来

2.边界值89991231的输入,因为这是输入的范围,要遍历的最大的年份要包含89991231下一个回文日期和ababbaba型回文日期,我果断开了一个9999的,没有超时。

代码部分:

  1. #include <iostream>
  2. using namespace std;
  3. //判断闰年;
  4. int check_year(int year)
  5. {
  6. if(year%4 == 0 && year%100 != 0 || year%400 == 0)
  7. return 1;
  8. else
  9. return 0;
  10. }
  11. //判断输入年份是否能生成合理日期,只传参数,后续判断做准备;
  12. int check_isRight(int year)
  13. {
  14. int month = year%100/10+year%10*10;
  15. int day = year/1000+year/100%10*10;
  16. if(month <= 12)
  17. if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 ||month == 10 || month == 12)
  18. {
  19. if(day <= 31)
  20. return 1;
  21. else
  22. return 0;
  23. }
  24. if(month == 4 || month == 6 || month == 9 || month == 11)
  25. {
  26. if(day <= 30)
  27. return 1;
  28. else
  29. return 0;
  30. }
  31. else if(month == 2)
  32. {
  33. if(check_year(year))
  34. {
  35. if(day <= 29)
  36. return 1;
  37. else
  38. return 0;
  39. }
  40. else
  41. {
  42. if(day <= 28)
  43. return 1;
  44. else
  45. return 0;
  46. }
  47. }
  48. else
  49. return 0;
  50. }
  51. //这里就体现出上面留一个参数的意义了,判断是否时abab型年份。
  52. int check_abab(int year)
  53. {
  54. if(check_isRight(year))
  55. {
  56. if(year%100 == year/100)
  57. return 1;
  58. else
  59. return 0;
  60. }
  61. else
  62. return 0;
  63. }
  64. int main()
  65. {
  66. int n;
  67. cin >> n;
  68. int o_year = n/10000;
  69. int month,day,m1,m2,d1,d2,ans1_year,ans2_year,flag1 = 0,flag2 = 0;//两个flag标记,第一个回文日期和第一个ababbaba日期
  70. for(int i = o_year; i <= 9999; i++)//遍历年份;
  71. {
  72. //用年份生成对应日期;
  73. month = i%100/10+i%10*10;
  74. day = i/1000+i/100%10*10;
  75. if(i*10000+month*100+day != n && i == o_year && check_isRight(i))//对输入日期的判断;
  76. {
  77. //这里不去管它也可以过的hhh
  78. if(i*10000+month*100+day > n)//输入在回文日期之前,保留;
  79. {
  80. ans1_year = i;
  81. flag1 = 1;
  82. m1 = month;
  83. d1 = day;
  84. }
  85. else//否则,丢弃;
  86. continue;
  87. }
  88. if(check_isRight(i) && flag1 == 0)//判断是否生成合法日期,若可以答案保留;
  89. {
  90. ans1_year = i;
  91. flag1 = 1;
  92. m1 = month;
  93. d1 = day;
  94. }
  95. if(check_abab(i) && flag2 == 0)//判断年份是否为abab型是否可以生成合法日期,若可以答案保留;
  96. {
  97. ans2_year = i;
  98. flag2 = 1;
  99. m2 = month;
  100. d2 = day;
  101. }
  102. if(flag1 == 1 && flag2 == 1)//两个结果都找到了跳出循环;
  103. break;
  104. }
  105. //输出结果;
  106. cout << ans1_year*10000+m1*100+d1 << endl;
  107. cout << ans2_year*10000+m2*100+d2;
  108. return 0;
  109. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/385423
推荐阅读
相关标签
  

闽ICP备14008679号