思想
题目我们需要满足两个要求,一个是从当前日期开始,找到基础版的回文日期,另一个是找到满足特殊要求的回文日期。
1:稍加思考可以发现一年至多一个回文日期。
2:输入的是整数,但不能单纯的个位数叠加,可以只叠加年份,日和月对应改动即可。
3:方便处理,转化成整型数组。这样容易判断特殊型的回文日期
注意:绝对不能字符串处理,后面天数判断时使用“数字”进行判断,而不是“char。”
4:月份的特殊性(最多12个月),导致年份的个位数进制从10进制变成2进制。
5:年份的++操作应该放在循环体结尾处:避免开始的一年漏选回文日期。
代码段
这里作者对闰年的数组处理变得复杂,导致代码量倍增(虽然也就是修改几个字符,但总归不好看)。
读者可以自行优化。
#include <bits/stdc++.h>
using namespace std;
int days1[] = {-111,31,28,31,30,31,30,31,31,30,31,30,31};
int days2[] = {-111,31,29,31,30,31,30,31,31,30,31,30,31};
int year;
int month;
int day;
int flag=0;
bool ifYear(int year)
{
if(year%4==0 && year%100!=0 || year%400==0)
return true;
return false;
}
void Game(int s[8])
{
while(true)
{
if(s[3]>1) //仅对年份进行叠加
{
s[2]++;
s[3] = 0;
if(s[2]>9)
{
s[1]++;
s[2]=0;
if(s[1]>9)
{
s[0]++;
s[1]=0;
if(s[0]>9)
return ;
}
}
}
s[4]=s[3];
s[5]=s[2];
s[6]=s[1];
s[7]=s[0];
year = s[0]*1000+s[1]*100+s[2]*10+s[3]; //年月日分开验证是否满足要求
month = s[4]*10+s[5];
day = s[6]*10+s[7];
if(ifYear(year))
{
// cout<<1;
if(days2[month]>=day && flag==0)
{
cout<<year*10000+month*100+day<<endl;
flag=1;
}
if(days2[month]>=day && s[0]==s[2] && s[1]==s[3]&&s[1]==s[4]&&s[0]==s[5]&&s[1]==s[6]&&s[0]==s[7])
{
cout<<year*10000+month*100+day;
return ;
}
}
else
{
// cout<<0;
if(days1[month]>=day && flag==0)
{
cout<<year*10000+month*100+day<<endl;
flag=1;
}
if(days1[month]>=day && s[0]==s[2] && s[1]==s[3]&&s[1]==s[4]&&s[0]==s[5]&&s[1]==s[6]&&s[0]==s[7])
{
cout<<year*10000+month*100+day;
return ;
}
}
s[3]++; //为什么最后加,我要查询当前年份是否有漏算。例如:20200201 当年有一个0202就是下一天,直接跳到下一年会忽略这个错误
}
}
int main()
{
int n;
cin>>n;
// n=10000101;
int s[8];
memset(s,0,sizeof(s));
int i=7;
while(n){ //短除法解决整数转换成数组,从数组尾进行存放数据
s[i] = n%10;
n/=10;
i--;
}
Game(s);
return 0;
}