ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

蓝桥杯日期模拟类问题总结

2022-03-26 21:02:04  阅读:162  来源: 互联网

标签:return int 31 蓝桥 mm 日期 dd 模拟


日期模拟几乎是蓝桥杯每年的必考题目,所以总结一下往年题目

【第八届】【省赛】日期问题

【问题描述】

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

  比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

  给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

【输入格式】

一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

【输入格式】

输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。

【样例输入】

02/03/04

样例输出

2002-03-04
2004-02-03
2004-03-02

#include<bits/stdc++.h>
using namespace std;

int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

bool cheak(int yy, int mm, int dd) {
	if (mm == 0 || mm > 12) return false;
	if (dd == 0) return false;
	if (mm == 2) {
		int leap = (yy % 4 == 0 && yy % 100) || (yy % 400 == 0);
		if (dd > days[mm] + leap) return false;
	} else {
		if (dd > days[mm]) return false;
	}
	return true;
}

int main()
{
    int a, b, c;
    scanf("%d/%d/%d", &a, &b, &c);
	for (int i = 19600101; i <= 20591231; i ++) {
		int yy = i / 10000, mm = i % 10000 / 100, dd = i % 100;
		if (cheak(yy, mm, dd)) {
			if (yy%100 == a && mm == b && dd == c) {
				printf("%d-%02d-%02d\n", yy, mm, dd);
			} else if (yy%100 == c && mm == a && dd == b) {
				printf("%d-%02d-%02d\n", yy, mm, dd);
			} else if (yy%100 == c && mm == b && dd == a) {
				printf("%d-%02d-%02d\n", yy, mm, dd);
			}
		}
	}
    
    return 0;
}

【第十一届】【省赛】【回文日期】

【问题描述】

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

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

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

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

【输入格式】

输入包含一个八位整数 N,表示日期。

【输入格式】

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

【样例输入】

20200202

样例输出

20211202
21211212

#include<bits/stdc++.h>
using namespace std;

int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool check (int yy, int mm, int dd) {
	if (!dd) return false;
	if (!mm || mm > 12) return false;
	int leap = (yy % 4 == 0 || yy % 100) || (yy % 400 == 0);
	if (mm == 2) {
		if (dd > day[mm] + leap) return false;
	} else {
		if (dd > day[mm]) return false;
	}
	return true;
}

bool huiwen(string s) {
	for (int i = 0, j = s.size()-1; i < j; i ++, j --) {
		if (s[i] != s[j]) return false;
	}
	return true;
}

bool ty(string s) {
	if (s[0] == s[1]) return false;
	char a = s[0], b = s[1];
	for (int i = 0; i < s.size(); i ++) {
		if (s[i] == a) s[i] = 'A';
		if (s[i] == b) s[i] = 'B';
	}
	if (s == "ABABBABA") return true;
	else return false;
}

int main()
{
	int n;
	cin >> n;
	int flag = 0;
	for (int i = n + 1; ; i ++) {
		int yy = i / 10000, mm = i % 10000 / 100, dd = i % 100;
		if (check(yy, mm, dd)) {
			string s;
			int k = i;
			while (k) {
				int x = k % 10;
				s += x+'0';
				k /= 10;
			}
			if (huiwen(s) && !flag) {
				cout << s << endl;
				flag = 1;
			}
			if (ty(s)) {
				cout << s;
				break;
			}
		}
	}
	return 0;
}

小结

通过上面两道题可以看出一个大致的套路都是通过暴力遍历每一个整数然后判断这个整数是否是一个正确的日期,总结为以下模板

int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool check (int yy, int mm, int dd) {
	if (!dd) return false;
	if (!mm || mm > 12) return false;
	int leap = (yy % 4 == 0 || yy % 100) || (yy % 400 == 0);
	if (mm == 2) {
		if (dd > day[mm] + leap) return false;
	} else {
		if (dd > day[mm]) return false;
	}
	return true;
}

标签:return,int,31,蓝桥,mm,日期,dd,模拟
来源: https://www.cnblogs.com/hanyj-home/p/16060824.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有