题目如下
题解思路:
这道题其实和 Fibonacci 数列与黄金分割【第十届】蓝桥杯 很相似,都是通过举例推出 ans 的大致范围
因为通过举例就可以发现,回文日期虽然区间大,但是真正满足的没有几个(一共360个左右?)
输出第一行(我称之为 《回文日期》)的规则是ABCDDCBA
第二行(我称之为 《回文日期 plus》)的规则是ABABBABA
ABABBABA 应该是 ABCDDCBA 的子集,所以我们可以先求回文日期,在给 回文日期 加上判定条件来求下一个 回文日期plus
之后第一反应就是枚举,但是数量太大,你不可能真的从10000000-89999999去试,怎么化简是一个问题
先枚举年份还是先枚举日期?
思考举例一下,确定是枚举日期,因为每个日期最多对应一个回文的年份,回文日期最多才366个
之后就是枚举,打表,记得写个比较函数bool cmp(),给datas排个序,简简单单的输入输出
本题收获:
需要注意的点!
1. 存储字符char的时候,假如我想存字符 '7' 就应该char num[0] = 7+'0',而不是直接赋值 7 ,因为这里存的是ASCII码
2. atoi/atof和stoi(字符转换数字函数)的区别在于,atoi可以给char型数组用,stoi只能给string类型的用
3. 捏麻麻的,刚开始没考虑闰年:年份是4的倍数且不是100的倍数,或是400的倍数
真的离谱,我的代码蓝桥杯官网下载的判题样例都能过,结果判题系统给我0分,我真的......😅
源码如下:
#include <iostream>
#include <stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
vector<string> datas;
char data1[9];
char year[4];
bool cmp(string a, string b)//比较日期大小
{
return a < b;//日期按从小到大排序
}
int main() {
for (int i = 1; i <= 12; i++) {
for (int j = 1; j <= 31; j++) {
if (j > 29 && i == 2) {
continue;
}
if (j > 30 && (i == 4 || i == 6 || i == 9 || i == 11)) {
continue;
}
int tem = 0;
tem = j % 10;
year[0] = tem+'0';
if (j < 10) {
year[1] = '0';
}
else {
year[1] = j / 10+'0';
}
tem = i % 10;
year[2] = tem+'0';
if (i < 10) {
year[3] = '0';
}
else {
year[3] = '1';
}
int year_num = atoi(year);
//cout << year_num << " ";
if (i == 29 && j == 2 && !((year_num % 4 == 0 && year_num % 100 != 0) || year_num % 400 == 0))//若不是闰年
continue;
tem = i * 100 + j + year_num * 10000;
for (int i = 7; i >= 0; i--) {
data1[i] = tem % 10+'0';
tem = tem / 10;
}
// cout << data1 << " ";
datas.push_back(data1);
}
}
sort(datas.begin(), datas.end(), cmp);//对所有回文日期做一个从小到大的排序
string str;
cin >> str;
int pos;
for (pos = 0; pos < datas.size(); pos++) {
if (datas[pos] > str) {
cout << datas[pos] << endl;
break;
}
}
for (; pos < datas.size(); pos++) {
if (datas[pos][0] == datas[pos][2] && datas[pos][1] == datas[pos][3]) {
cout << datas[pos];
break;
}
}
return 0;
}