首页 > 其他分享 >[Luogu P8716] 回文日期 题解

[Luogu P8716] 回文日期 题解

时间:2023-08-15 14:24:32浏览次数:39  
标签:10 P8716 int 题解 yy 日期 && Luogu 回文

STEP 1:分析

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

这一题一眼看出是 P2010 的升级版,所以要先考虑到超时问题,因为如果一天一天地枚举,时间复杂度会非常高,所以我们不能直接枚举。因为题目只要"回文",所以我们只要一个个扫描年份,再根据年份的反转数得到日期,并判断得出的日期是否合法,记得闰年特判,就能得出答案了。

STEP 2:构建

判断闰年函数

bool rn(int yy) {
	return (yy % 400 == 0) || (yy % 4 == 0 && yy % 100 != 0);
	/*能被400整除的或不是整百能被4整除的都是闰年*/
}

构建反转函数

int rev(int x) {
	int sum;
	for (sum = 0; x; x /= 10) sum = sum * 10 + x % 10;
	/*循环将x的最后一位加到sum后面,类似栈的想法(后进先出)*/
	return sum;
}

构建两种判断

这里需要注意:

  1. 要判断闰年
  2. 不能算错日期

这里有两种判断(普通回文日期和 ABABBABA 型日期),可以试着利用普通回文日期的判断减少 ABABBABA 型日期判断的码量。

bool check(int yy) {
	if (rn(yy)) mon[2] = 29; // 闰年的特判
	else mon[2] = 28;        // 重点!mon数组在不是闰年时一定要清零
	int mm = (yy % 10) * 10 + (yy / 10 % 10);    // 年份后两位反转得出几月
	int dd = (yy / 100 % 10) * 10 + (yy / 1000); // 年份前两位反转得出几日
	return mm >= 1 && mm <= 12 && dd >= 1 && dd <= mon[mm]; 
	// 判断月份是否在 1~12 的范围内, 日期是否在当月的范围内
}
bool ABABBABA(int yy) {
	return check(yy) && // 这里可以不用再写一次了
		(yy % 10 == yy / 100 % 10) && 
		(yy / 10 % 10 == yy / 1000); 
		// 只要判断年份是否为 “ABAB” 就行了,因为已经判断回文
}

主函数

在主函数里,有一个非常重要的环节:特判当前年份有没有这两个种类的回文日期,因为不是按日期枚举,所以无法从给定的日期开始枚举,那么就需要特判。

cin >> n;
yy = n / 10000;
mm = n / 100 % 100;
dd = n % 100;
int dt = rev(yy), dmm = dt / 100 % 100, ddd = dt % 100;
if (ABABBABA(yy) && (dmm > mm || (dmm == mm && ddd > dd))) {
	check2 = yy; // 在给定日期之后的第一个ABABBABA型日期
}
if (check(yy) && (dmm > mm || (dmm == mm && ddd > dd))) {
	check1 = yy; // 在给定日期之后的第一个回文日期
}

好了,最后我们只要枚举以后的年份,直到找到答案。

for (int i = yy + 1; ; i++) {
	if (check1 != -1 && check2 != -1) break;
    // 两个目标都找到了,退出
	if (ABABBABA(i) && check2 == -1) check2 = i;
    // 保存ABABBABA型日期
	if (check(i) && check1 == -1) check1 = i;
    // 保存回文日期
}
printf("%04d%04d\n%04d%04d", check1, rev(check1), check2, rev(check2));

所有的步骤都分析完了,请读者自行完成完整代码\ 制作不易,希望这篇题解能有些用处~

标签:10,P8716,int,题解,yy,日期,&&,Luogu,回文
From: https://www.cnblogs.com/atronomia/p/problem-solution-of-luogu-p8716.html

相关文章

  • [JOI 2023 Final] Advertisement 2 题解
    题解JOI王国有\(N\)位居民,从\(1\)到\(N\)编号。居民\(i\)(\(1\lei\leN\))居住在数轴上坐标\(X_i\)处,其影响力为\(E_i\)。同一个坐标可能住了多于一位居民。居民的影响力越高,广告效应也越高,但买书也越谨慎。Rie出版了一本关于信息学的书。为了让更多人购买这本书,她可......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——深度学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我将有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点......
  • P3629 巡逻 LCA题解
    原题:洛谷P3629问题转化首先,给定的图是一个有\(n\)个点,\(n-1\)条边的无向连通图,这个图就等价于一棵树。不建立新的道路时,从\(1\)号节点出发,把整棵树上的每条边遍历至少一次,再回到\(1\)号节点,会恰好经过每条边两次,路线总长度为\(2(n-1)\),如下图最左边的部分所示。根据树......
  • SVN 不显示红绿图标问题解决方案
    本地文件夹我们先在桌面或者资源管理器中鼠标右键打开设置  选择IconOverlays(图标覆盖) Status cache(状态缓存)选择‘Shell’ 接着选择IconOverlays(图标覆盖)下的IconSet(图标集)  选择应用然后确认,重启生效     ssh等方式挂载的远程磁盘......
  • 2019考研英语(一)小作文真题解析与参考 Aiding Rural Primary Schools 答复信
    2019考研英语(一)小作文真题解析与参考Directions:Supposeyouareworkingforthe“AidingRuralPrimarySchools” projectofyouruniversity.Writeanemailtoanswertheinquiryfromaninternationalschoolvolunteer,specifyingthedetailsoftheproject.Yous......
  • 2023NepCTF-RE部分题解
    2023NepCTF-RE部分题解九龙拉棺过反调试很容易发现void__stdcallsub_401700()里面有tea的痕迹接出来发现只是前半部分#include<stdio.h>#include<stdint.h>#include"defs.h"#include<stdio.h>#include<stdio.h>#include<stdint.h>//加密函数......
  • CodeForces-1798#B 题解
    正文开个数组\(last_k\)统计\(a_{i,j}\)最后买彩票的时间,再开一排桶\(day_t\)记录该天最后买彩票的有哪些人(即:有\(p\)满足\(last_p=t\)的集合)。将\(last_k\)放入\(day_t\)中,判断\(day_t\)中是否存在空桶,若有则无解(因为没有人在当天是最后买彩票的)。因为本题是......
  • 题解 CF379D New Year Letter
    思路提供一种比较容易想到的做法。拿到题看数据范围发现都很小,所以放心大胆地暴力。容易发现\(s_i\)中AC的个数等于\(s_{i-2}\)中AC的个数加\(s_{i-1}\)中AC的个数再加上两者拼接处可能有的一个AC。所以\(s_1\)和\(s_2\)从第二个字符到倒数第二个字符这之间......
  • P4412 题解
    P4412题解传送门更好的阅读体验简化题意:一张无向图,给定一棵生成树,求最小的修改边权的代价使得这棵生成树是最小生成树,代价定义为修改前后一条边的边权变化量的绝对值。思路首先,发现让这棵树成为最小生成树不好直接处理,但是判定是否为最小生成树却相对更容易。判定的思路......
  • CF1845D Rating System 题解
    题面给定一个长度为\(n\)数列\(a\),保证每项都不为\(0\)。初始时\(x=0\),然后对于\(1\lei\len\),按顺序进行如下操作:如果\(x\gek\),则\(x\rightarrow\max(k,x+a_i)\),否则\(x\rightarrowx+a_i\)。你需要求出\(k\),使得\(x\)的值尽量大。题解如果我们不考虑\(k......