[day1] 第十一届蓝桥杯大赛第二场省赛试题——回文日期

问题描述

       2020年春节期间,有一个特殊的日期引起了大家的注意: 2020年2月2日。因为如果将这个日期按“yyyymmdd"的格式写成-一个8位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。
       有人表示20200202是“千年一遇” 的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期: 20211202 即2021年12月2日。
       也有人表示20200202 并不仅仅是一个回文日期,还是一ABABBABA型的回文日期。对此小明也不认同,因为大约100年后就能遇到下一个ABABBABA型的回文日期: 21211212 即2121 年12月12日。算不上“千年一遇”,顶多算“千年两遇”。
       给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。

思路

年份的范围就是1000——9999,每个年份的回文日期就是该年份反转过来变成月份。

例如:

1011年的回文日期是 1011 1101
1201年的回文日期是 1201 1021 
2020年的会问日期是 2020 0202

我们只需要获取八位整数N前面4位的年份即可。我们将每一个年份,先进行反转,和原本年份拼成一个8位的字符串,需要判断回文日期是不是有效的日期 (”20222202“就不是一个有效的回文日期,因为月份22,大于12)。这个字符串必定是回文字符串。接着就需要找到下一个ABABBABA型的回文日期。

#include
using namespace std;
//判断回文ababbaba形状日期
bool is_ab(string s){
	if(s[0]-'0'==s[2]-'0'&&s[1]-'0'==s[3]-'0')
		return true;			
	return false;
}

bool judge(string s){//判断是日期否有效
	//月份是否有效
	if(s[4]-'0'>=2 || s[6]-'0'>=4)
		return false;
	if(s[4]-'0'==1 && s[5]-'0'>2)
		return false;
	//每月号数是否有效
	if(s[6]-'0'==3 && s[7]-'0'>=2) return false;
	
	//2月是否超过28  不用需要考虑闰年,因为闰年都不符合要求
	if(s[4]=='0'&&s[5]=='2'){
		if(s[6]-'0'==2 && s[7]-'0'>7) return false;
	}
	//31天的月份
	if(s[5]-'0'==1||s[5]-'0'==3||s[5]-'0'==5||s[5]-'0'==6||s[5]-'0'==7||s[5]-'0'==8||(s[4]-'0'==1&&s[5]-'0'==0)||(s[4]-'0'==1&&s[5]-'0'==2)){
		if(s[6]-'0'==3 &&s[7]-'0'>1)
			return false;
	}
	//30天的月份
	if(s[5]-'0'==4||s[5]-'0'==6||s[5]-'0'==9||(s[4]-'0'==1&&s[5]-'0'==1)){
		if(s[6]-'0'==3 &&s[7]-'0'>0)
			return false;
	}
	return true;
}

void func1(int number){
	int n=number/10000;//获取年份
	string s,s1;
	vector<string> nums;
	for(int m=n+1;m<10000;m++){
		s=to_string(m);
		s1=s;
		reverse(s1.begin(),s1.end());
		s+=s1;//拼接成一个回文串
		if(judge(s)){//回文串是否是有效的日期
			nums.push_back(s);
		}
	}
	cout<<nums[0]<<endl;//第一个有效回文日期
	for(auto& x:nums){
		if(is_ab(x)){
			cout<<x<<endl;		//第一个ababbaba的日期	
			break;
		}

	}
}
int main(){
	func1(20200202);
}

你可能感兴趣的:(C++,蓝桥杯,职场和发展)