备战蓝桥杯(日益更新)(刷题)

news2024/11/25 22:41:41

备战蓝桥杯(日益更新)(刷题)


文章目录

  • 备战蓝桥杯(日益更新)(刷题)
  • 前言:
  • 一、二分:
    • 1. acwing503 借教室:(二分 + 差分)
    • 2. acwing1227 分巧克力:(二分 + 数学推导计算)
    • 3. acwing5407 管道(二分、区间合并、差分)
  • 二、前缀和:
    • 1. acwing562 壁画(向上取整 + 前缀和)
    • 2. acwing1230 K倍区间(前缀和 + “同余数相减是倍数?”)
  • 三、差分:
    • 1.acwing4262 空调(差分 + “一加一减求最大”)
    • 2. acwing5396 棋盘(二维差分 + “%2 和 &1”)
  • 四、双指针:
    • 1. acwing3745 牛的学术圈1(h指数)(双指针)
    • 2. acwing4405 统计子矩阵
  • 五、归并排序:
  • 六、多路归并:
  • 七、贡献法:
    • 1. acwing4261 孤独的照片
  • 八、日期问题:
    • 1. acwing3498 日期差值:
    • 2. acwing2867 回文日期:
  • 九、区间合并:
  • 十、递归:
  • 十一、DFS:
  • 十二、回溯:
  • 十三、BFS:
  • 十四、Flood Fill:
  • 十五、并查集:
  • 十六、哈希:
  • 十七、单调队列:
  • 十八、树状数组:
  • 十九、状态压缩dp:
  • 二十、线性dp:
  • 二十一、背包问题:
  • 二十二、区间dp:
  • 二十三、树状dp:
  • 二十四、快速幂:
  • 二十五、最大公约数:
  • 二十六、分解质因数:
  • 二十七、矩阵乘法:
  • 二十八、组合计数:
  • 二十九、数学期望:
  • 三十、欧拉函数:
  • 三十一、最短路:
  • 三十二、贪心:
  • 三十三、括号序列:
  • 总结


前言:

刷题ing😊 刷题ing😊 刷题ing😊


提示:以下是本篇文章正文内容:

一、二分:


1. acwing503 借教室:(二分 + 差分)


在这里插入图片描述



/*
题目:我们须要处理n天的借教室的信息,其中第i天学校有ri个教室可以使用。
共有m份订单,每份订单用三个正整数描述,分别为dj,sj,tj,
表示某租借者要从sj天到tj天租借教室(包含sj、tj天)(就是包头包尾),每天租借dj个教室。
如果在分配过程中,遇到一份订单无法完成,则需要停止教室分配,通知当前申请人修改订单。
现在,我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单?

输入:
第一行包含2个正整数n,m,表示天数和订单数量。
第二行包含n个正整数,其中第i个数表示ri。
接下来由m行,每行包含3个正整数,表示dj,sj,tj。
每行相邻的两个数之间均使用一个空格隔开。
天数与订单均从1开始编号。

输出:
如果所有的订单满足,则输出只有1行,包含一个整数0.
否则,输出两行,第一行输出一个-1,第二行输出需要修改订单的申请人编号。

数据范围:
1 < n,m < 10^6
0 < ri, dj < 10^9
1 < sj, tj < n
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;

typedef long long LL;

int n, m;
int r[N], d[N], s[N], t[N];
LL b[N];

// 判断订单是否 不可以完成,如果不可以完成,返回true,可以完成,返回false。 
bool check(int mid)
{
	for(int i = 1; i <= n; i ++) b[i] = r[i] - r[i - 1];// 差分初始化 
	for(int i = 1; i <= mid; i ++)// 一个区间里面的数都 减去 一个d[i] 
	{
		b[s[i]] -= d[i];
		b[t[i] + 1] += d[i];	
	}
	// 求前缀和 
	for(int i = 1; i <= n; i ++)
	{
		b[i] += b[i - 1];
		if(b[i] < 0) return true;
	}
	return false;
}

int main()
{
 	scanf("%d%d", &n, &m);
 	for(int i = 1; i <= n; i ++) scanf("%d", &r[i]);
 	for(int i = 1; i <= m; i ++) scanf("%d%d%d", &d[i], &s[i], &t[i]);
 	
 	// 如果全部订单可以完成,直接打印0. 
 	if(!check(m))
 	{
 		puts("0");
 		return 0;
	 }
	 
	 // 否则,二分寻找那个 需要修改订单的申请人编号
	 int l = 1, r = m;
	 while(l < r)
	 {
	 	int mid = (l + r) >> 1;
	 	if(check(mid)) r = mid;// 1 ~ mid的范围有,向又收缩 
	 	else l = mid + 1;
	  } 
	
	printf("-1\n%d\n", r);// 找到打印 
	return 0;
}

在这里插入图片描述



2. acwing1227 分巧克力:(二分 + 数学推导计算)


在这里插入图片描述



在这里插入图片描述



/*
有K个人,有N块巧克力,其中第i块是Hi*Wi的方格组成的长方形
要从这N块巧克力切出K块巧克力分给他们。
切除的巧克力须要满足:1.是正方形  2.大小相同
例如:一块6*5的巧克力可以切出6块2*2的巧克力或者2块3*3的巧克力。
希望得到的巧克力尽可能的大,请计算出最大的边长是多少?

输入:(输入保证每位小朋友至少能获得一块1*1的巧克力)
第一行包含2个整数N和K
一下N行包含两个整数Hi 和 Wi

输出:
输出最大可能的边长

数据范围:
1 < N, K < 10^5
1 < Hi, Wi < 10^5
*/

#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

int n, m;
int h[N], w[N];// 长, 宽 

// 二分“二段性”的判断条件 
bool check(int mid)
{
	LL res = 0;
	for(int i = 0; i < n; i ++)
	{
		// 加括号:先乘积 后下取整 != 先下去整 后乘积
		// 例如:2 *(3/4) != 2 * 3 / 4 
		res += (LL)h[i] / mid * (w[i] / mid); 
		if(res >= m) return true;
	}
	return false;
}


int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i ++) scanf("%d%d", &h[i], &w[i]);
	
	// 长度和宽度最大为 1e5 
	int l = 1, r = 1e5;
	while(l < r)
	{
		int mid = l + r + 1 >> 1;// 向上取整 
		if(check(mid)) l = mid;
		else r = mid - 1;
	}
	
	printf("%d\n", r);
	return 0;
}

在这里插入图片描述



3. acwing5407 管道(二分、区间合并、差分)


在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



/*
有一根长度为 len 的横向的管道,该管道按照单位长度分为 len 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器
一开始管道是空的,位于 Li 的阀门会在 Si 时刻打开,并不断让水流入管道。
对于位于 Li 的阀门,它流入的水在 Ti(Ti >= Si)时刻会使得从第 Li - (Ti - Si)段到 Li + (Ti - Si) 段的传感器检测到水流。
求管道中每一段中间的传感器都检测到有水流的 最早时间。

输入:
第一行:n, len分别表示会打开的阀门数和管道长度
接下来n行包含Li 和 Si,表示位于第Li段管道的阀门会在Si时刻打开

输出:
一个整数

数据范围:
对于30%的测试用例,n <= 200, 1 <= si, len <= 3000
70%,  n <= 5000, si, len <= 5000
100%,  n <= 10^5, si, len <= 10^9, 
*/

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

#define x first
#define y second

typedef pair<int, int> PII;
typedef long long LL;

const int N = 1e5 + 10;

int n, m;// 会打开n个阀门, 有m段管道 
PII w[N], q[N];
// w: 位于 Li 的阀门会在 Si 时刻打开,并不断让水流入管道。(注意1) 
// p: 二分后,每个区间对应的左右端点 

// 判断mid时刻是否可以覆盖完所有的位置:
bool check(int mid)
{
	int cnt = 0;// 区间数量 
	for(int i = 0; i < n; i ++)
	{
		int L = w[i].x, S = w[i].y;// 位置,打开时刻 
		if(S <= mid)// 时间 
		{
			int t = mid - S;// 距离S经过多长时间 
			// 确定左右端点 (阀门扩散水)
			// max,min:保证 左右端点 在范围内。 
			int l = max(1, L - t), r = min((LL)m, (LL)L + t);// L + t 爆int (注意2) 
			q[cnt ++] = {l, r}; 
		}
	}
	// 按照区间的左端点  升序排序 (注意3) 
	sort(q, q + cnt);
	
	 int st = -1, ed = -1;
	 // 遍历所有区间: 
	 for(int i = 0; i < cnt; i ++)
	 {
	 	// 注意:ed + 1,就是不用重合,也要合并(注意4) 
		// 看end端点,如果end+1端点小于st的话,说明一个区间已经合并完毕。
		// 否者就是判断区间是否要扩展,从两个end的中去最大值。 
	 	if(q[i].x <= ed + 1) ed = max(ed, q[i].y);
	 	else st = q[i].x, ed = q[i].y;
	  } 
	  // 判断合并区间的结果是否满足要求。 
	  return st == 1 && ed == m;
}


int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i ++) scanf("%d%d", &w[i].x, &w[i].y); 
	
	// 2e9:第一个点,在1e9时刻打开阀门,且管道长度为1e9,所以最慢在2e9时刻 都能检测到水 
	int l = 0, r = 2e9;
	while(l < r)
	{
		int mid = (LL)l + r >> 1;// 2e9
		if(check(mid)) r = mid;
		else l = mid + 1;
	 } 
	
	printf("%d\n", r);
	return 0;
}

在这里插入图片描述



二、前缀和:


1. acwing562 壁画(向上取整 + 前缀和)

在这里插入图片描述



在这里插入图片描述



/*
有N段壁画,每段壁画上面都有一个美观评分(如果它的上面有画的话)
不幸的是,由于洪水泛滥,墙体开始崩溃。
每天可以绘制一段墙体,在第一天,可以自由的选择一段墙面进行绘制。
在接下来的每一天,只能选择与绘制完成的墙面相邻的墙进行作画。
每天结束的时候,一段未被涂颜料的墙将被摧毁(防水颜料),“且毁掉的墙一定只能与一段还未被毁掉的墙面相邻”。
壁画的总体美观程度等于它作画的所有的墙面的美观评分的总和。
要保证,无论墙壁是如何被摧毁的,都可以达到至少B的美观总分。
请问,可以保证达到的美观总分B的最大值是多少?(这个题目叙述,我也是醉了)

输入:
第一行包含整数T,表示有T组测试数据
接下来由T组:
第一行输入一个整数N
第二行行包含一个长度为N的字符串,字符串有数字0 ~ 9构成,第i个字符表示第i段墙面被上色后能达到的美观评分。

输出:
每组数据输出一个结果,每个结果占一行。
结果表示:Case #x:y
其中x为组别编号,y为可以保证达到的美观评分的最大值。

数据范围:
1 <= T <= 100, 2 <= N <= 5*10^6
*/
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5000010;

int n;
int s[N];// 前缀和数组 
char str[N];// 字符串 

int main()
{
	int T;
	scanf("%d", &T);
	
	for(int cases = 1; cases <= T; cases ++)
	{
		scanf("%d", &n);
		scanf("%s", str + 1);// 字符串从索引为1的位置开始录入。
		for(int i = 1; i <= n; i ++)// 求前缀和 
			s[i] = s[i - 1] + str[i] - '0';// 注意1:字符边int数 
			
		int res = 0, m = (n + 1) / 2;// 注意2:向上取整 
		for(int i = m; i <= n; i ++)
			res = max(res, s[i] - s[i - m]);// 遍历,找到长度为m的最大区间和 
		 
		 printf("Case #%d:%d\n", cases, res);
	}
	
	return 0;
} 


在这里插入图片描述



2. acwing1230 K倍区间(前缀和 + “同余数相减是倍数?”)


在这里插入图片描述



在这里插入图片描述



/*
给定一个长度为N的数列,A1, A2, ... ,AN  如果其中一段连续的子序列  Ai,  ... , Aj    的和是K的倍数,我们就称这个区间[i, j]是K倍区间。
求出数列中总共有多少个K倍区间?

输入:
第一行包含2个整数 N 和 K
以下N行每行都包含一个整数Ai

输出:
输出一个整数,表示K倍区间的数量

数据范围:
1 <= N, K <= 10^6
1 <= Ai <= 10^6
*/

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1e5 + 10;
typedef long long LL;

int n, k;
LL s[N];
int cnt[N];

int main()
{
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i ++)
	{
		// 输入数据的时候 ,顺便求前缀和数组 
		scanf("%d", &s[i]);
		s[i] += s[i - 1];
	}
	
	LL res = 0;
	cnt[0] ++;
	for(int i = 1; i <= n; i ++)
	{
		res += cnt[s[i] % k];
		cnt[s[i] % k] ++;
	 } 
	
	printf("%lld\n", res);// 打印的时候要注意是 long long 
	return 0;
}

在这里插入图片描述



三、差分:


1.acwing4262 空调(差分 + “一加一减求最大”)

在这里插入图片描述



/*
有N头奶牛对牛棚的室温十分挑剔,有的喜欢温度低一些,而有的喜欢高一些
奶牛编号从1到N,每个牛栏里有一头奶牛
第i头奶牛希望她的牛栏中的温度是pi,而现在她的牛栏中的温度是ti
为了确保每一头奶牛都感到舒适,安装了一个新的空调系统
该系统进行控制的方式非常有趣,它可以向系统发送命令,告诉它将一组连续的牛栏的温度都升高1个单位或降低。
一组连续的牛栏最短可以包含一个1个。
求出空调系统发送命令的最小数量。

输入:
第一行包含N
下一行包含N个非负整数   p1 ... pn
最后一行包含N个非负整数t1 ... tn

输出:
一个整数,须要使用的最小指令数

数据范围:
1 <= N <= 10^5
0 <= pi, ti <= 10^4
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010; 

int n;
int a[N]; // A  A-B  A-B的差分 


int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
	// 直接在原数组里面操作,求出 A-B 
	for(int i = 1; i <= n; i ++) 
	{
		int b;
		scanf("%d", &b);
		a[i] -= b;
	}
	// 从后往前求出A-B的差分数组 
	for(int i = n; i; i --) a[i] -= a[i - 1];
	 
	int pos = 0, neg = 0;// 正数之和  负数之和 
	for(int i = 1; i <= n; i ++)
	{
		if(a[i] > 0) pos += a[i];
		else neg -= a[i];// 直接求负数的绝对值 
	 } 
	
	printf("%d\n", max(pos, neg)); 
	return 0;
 } 

在这里插入图片描述



2. acwing5396 棋盘(二维差分 + “%2 和 &1”)

在这里插入图片描述

/*
小蓝拥有n*n大小的棋盘,一开始棋盘上全是白子。
小蓝进行了m次操作,每次操作会将棋盘上某个范围内所有的棋子的颜色取反
(也就是白子变黑子,黑子变白子)
请输出所有操作做完后,棋盘上每个棋子的颜色。

输入:
第一行包含2个整数n,m,表示棋盘大小,操作数
接下来m行,每行包含4个整数
x1,y1,x2,y2,表示将(x1, y1)和 (x2, y2) 范围内的棋子颜色取反。

输出:
输出n行,每行n个0或1表示该位置棋子的颜色。
白色0,黑色1.

数据范围:
30%     1 <= n, m <= 500
100%    1 <= n, m <= 2000   1<= x1, x2, y1, y2 <= n
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 2010;

int n, m;
int b[N][N];

int main()
{
	scanf("%d%d", &n, &m);
	while(m --)
	{
		int x1, y1, x2, y2;
		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
		
		// 差分:一个矩阵范围都 +/- 去一个数 
		b[x1][y1] ++;
		b[x1][y2 + 1] --;
		b[x2 + 1][y1] --;
		b[x2 + 1][y2 + 1] ++;
	}
	
	for(int i = 1; i <= n; i ++)
	{
		for(int j = 1; j <= n; j ++)
		{
			b[i][j] += b[i - 1][j] +b[i][j - 1] - b[i - 1][j - 1];// 差分还原为前缀和 
			printf("%d", b[i][j] & 1);// 相当于b[i][j] % 2 
		}
		puts("");// 换行 
	}
	
	return 0;
}

在这里插入图片描述



四、双指针:


1. acwing3745 牛的学术圈1(h指数)(双指针)


在这里插入图片描述



/*
Bessie发表了N篇论文,并且她的第i篇论文得到了ci次其他论文的引用。
h指数等于使得研究员至少h篇引用次数不少于h的论文的最大整数。
例如,如果一名研究员有4篇论文,引用次数分别为(1, 100, 2, 3),则h指数为2,然而若引用次数为(1, 100, 3, 3)。
为了提升她的h指数,Bessie计划写一篇综述,并引用她曾经写过的论文。
由于页数限制,她最多可以引用L篇论文,并且“她只能引用每篇她的论文至多一次”
请帮助Bessie求出在写完这篇综述后,她可以达到的最大h指数。
注意:Bessie的导师可能会告知她纯粹为了提升h指数而写综述是违反学术道德的。

输入:
第一行包含N 和 L 
第二行宝行c1 ,..., cn

输出:
可以达到的最大h指数

数据范围:
1 <= N <= 10^5
0 <= ci <= 10^5
0 <= L <= 10^5
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, L;
int q[N];

int main()
{
	scanf("%d%d", &n, &L);
	for(int i = 1; i <= n; i ++) scanf("%d", &q[i]);
	sort(q + 1, q + n + 1, greater<int>());// 降序排序 
	
	int res = 0; 
	// 双指针i,j 
	// i - j表示的是h-1的个数 
	for(int i = 1, j = n; i <= n; i ++)
	{
		while(j && q[j] < i) j --;// q[j] >= i
		if(q[i] >= i - 1 && i - j <= L)
			res = i;
	 } 
	
	printf("%d\n", res);
	return 0;
 } 

在这里插入图片描述


在这里插入图片描述



2. acwing4405 统计子矩阵


在这里插入图片描述



在这里插入图片描述



/*
给定一个N*M的矩阵A,请你统计有多少个子矩阵(最小1*1,最大N*M)满足子矩阵中所有数的和不超过给定的整数K。

输入:
第一行包含3个整数N, M 和 K
之后N行每行包含M个整数,代表矩阵A。

输出:
一个整数表示答案。

数据范围:
30%    N, M <= 20
70%    N, M <= 100
100%  1 <= N, M <= 500     0 <= Aij <= 1000
*/
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 510;

int n, m, k;
int s[N][N];


int main()
{
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= m; j ++)
		{
			scanf("%d", &s[i][j]);
			s[i][j] += s[i - 1][j];// 动态求 列 的前缀和 
		}
	
	LL res = 0;
	for(int i = 1; i <= n; i ++)// 上边界 
		for(int j = i; j <= n; j ++)// 下边界 
			for(int l = 1, r = 1, sum = 0; r <= m; r ++)// 用双指针枚举左右边界 
				{
					sum += s[j][r] - s[i - 1][r];// 加上第r列 
					while(sum > k) 
					{
						sum -= s[j][l] - s[i - 1][l];// 删掉第l列 
						l ++;
					 } 
					 res += r - l + 1;// 方案数 
				}
	
	printf("%lld\n", res);
	return 0;
}


在这里插入图片描述



五、归并排序:

六、多路归并:

七、贡献法:


1. acwing4261 孤独的照片

在这里插入图片描述



在这里插入图片描述



/*
john购买了N头新的奶牛,有G和H两种品种
奶牛排成一排,john想要为每个连续不少于3头奶牛的序列拍摄一张照片。
孤独的照片:其中只有一头牛的品种是 G 或 H。
他最后会把所有的“孤独的照片”给扔掉。
给定奶牛的排列方式,求出john会扔掉多少张“孤独的照片”。
如果两张照片以不同位置的奶牛开始 或 结束,则认为它们是不同的。

输入:
第一行包含N
第二行包含长度为N的字符串。(内容是G 或 H)

输出:
扔掉的数量

数据范围:
3 <= N <= 5*10^5
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 500010;

int n; 
char str[N];
int l[N], r[N];// 每个字符的左/右边,连续出现与本身不同字符的个数。 

int main()
{
	scanf("%d", &n);
	scanf("%s", str);
	
	// 如果出现的字符是G,那么l[i]为h,而且将h重置,然后g++ 
	for(int i = 0, h = 0, g = 0; i < n; i ++)
		if(str[i] == 'G') l[i] = h, h = 0, g ++;
		else l[i] = g, g = 0, h ++;
		
	for(int i = n - 1, h = 0, g = 0; i >= 0; i --)
		if(str[i] == 'G') r[i] = h, h = 0, g ++;
		else r[i] = g, g = 0, h ++;
		
	LL res = 0;
	for(int i = 0; i < n; i ++)
		// 注意:l[i] 或 r[i] 可能会是0. 
		res += (LL)l[i] * r[i] + max(l[i] - 1, 0) + max(r[i] - 1, 0);
	
	printf("%lld", res);
	return 0;
}

在这里插入图片描述



八、日期问题:


1. acwing3498 日期差值:


在这里插入图片描述



/*
有两个日期,求两个日期之间的天数,如果两个日期是连续的,
我们规定它们之间的天数为2天。(包头包尾)

输入:输入包含多组数据
每组数据占2行,分别表示2个日期,形式为YYYYMMDD

输出:
每组数据输出一行,即日期差值

数据范围:
年份范围[1, 9999],保证输入的日期合法。测试的数据组数不超过100.
*/

#include <iostream>
#include <algorithm>
#include <cstring>
// #include <cmath> 

using namespace std;

// 平年每月的天数 
const int months[] = {
	0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

// 判断是否是闰年,是闰年就要“返回+1” 
int is_leap(int year)
{
	// 不能被100整除,可以被4整除  或  可以被400整除 
	if(year % 100 && year % 4 == 0 || year % 400 == 0)
		return 1;
	return 0;
}

// 获取year年month月的天数 
int get_month_days(int year, int month)
{
	int res = months[month];
	if(month == 2) res += is_leap(year);// 闰年2月天数+1 
	return res;
}

// 获取 从y年m月d日 总天数 
int get_total_days(int y, int m, int d)
{
	// 年 
	int res = 0;
	for(int i = 1; i < y; i ++)
		res += 365 + is_leap(i);
	// 月
	for(int i = 1; i < m; i ++)
		res += get_month_days(y, i);
	// 日	
	return res + d;
}


int main()
{
	int y1, m1, d1, y2, m2, d2;
	// scanf的返回值是成功读取的输入项的数量,
	// 如果达到文件末尾或发生输入错误,它会返回EOF(通常是-1)。
	// %04d表示读取一个整数,并且这个整数至少占用4位数字,如果不足4位则在前面补0。
	// 这通常用于读取年份,如2023。
	while(scanf("%04d%02d%02d", &y1, &m1, &d1) != -1)
	{
		scanf("%04d%02d%02d", &y2, &m2, &d2);
		printf("%d\n", abs( get_total_days(y1, m1, d1) - get_total_days(y2, m2, d2) ) + 1);
	}
	return 0;
 } 

在这里插入图片描述



2. acwing2867 回文日期:


/*
日期按“yyyymmdd”的格式写成一个8位数是回文数,那么这个日期就是 普通回文日期。
还有 特殊的回文日期:ABABBABA类型的。
例子:20200202、20211202、21211212 
给定一个8位数的日期,请你计算该日期之后的下一个回文日期和下一个ABABBABA类型的回文日期各是哪一天?(有可能相等)
注意:本题一定有解

输入:
一个8为整数N

输出:2行
第1行表示下一个回文日期
第2行表示下一个ABABBABA类型的回文日期

数据范围:
1000 01 01 < N < 8999 12 31  (保证N合法)
*/

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

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

int is_leap(int year)
{
	if(year % 100 && year % 4 == 0 || year % 400 == 0)
		return 1;
	return 0;
}

// 获取y年m月有多少天 
int get_days(int y, int m)
{
	if(m == 2) return 28 + is_leap(y);
	return months[m];
}

// 天数+1 
// d+1,可能到下一月份,m+1可能到下一年 
void next_day(int& y, int& m, int& d)
{
	d ++;
	if(d > get_days(y, m))
	{
		d = 1;
		m ++;
		if(m > 12)
		{
			m = 1;
			y ++;
		}
	}
}

// 检查是否是回文串 
bool check1(char s[])
{
	for(int i = 0, j = 7; i < j; i ++, j --)
		if(s[i] != s[j])
			return false;
	return true;
}

// 检查是否是ABABBABA类型的回文串 
bool check2(char s[])
{
	// 只用判断前4个就好 
	char a = s[0], b = s[1], c = s[2], d = s[3];
	if(a == c && b == d && a != b)
		return true;
	return false;
}


int main()
{
	int y, m, d;
	scanf("%04d%02d%02d", &y, &m, &d);
	
	char s[10] = {0};
	
	bool found1 = false, found2 = false;// 标志 
	while(!found1 || !found2)
	{
		next_day(y, m, d);// 下一天 
		// 注意1:将三个整数y、m和d按照指定的格式"%04d%02d%02d"写入字符串s中。 
		sprintf(s, "%04d%02d%02d", y, m, d);
		if(check1(s))
		{
			if(!found1)
			{
				puts(s);
				found1 = true;
			}
			// 在是回文串的基础上,判断是否满足 第二个条件 
			if(!found2 && check2(s))
			{
				puts(s);
				found2 = true;
			}
		}

	}

	return 0;
 } 

在这里插入图片描述



九、区间合并:

十、递归:

十一、DFS:

十二、回溯:

十三、BFS:

十四、Flood Fill:

十五、并查集:

十六、哈希:

十七、单调队列:

十八、树状数组:

十九、状态压缩dp:

二十、线性dp:

二十一、背包问题:

二十二、区间dp:

二十三、树状dp:

二十四、快速幂:

二十五、最大公约数:

二十六、分解质因数:

二十七、矩阵乘法:

二十八、组合计数:

二十九、数学期望:

三十、欧拉函数:

三十一、最短路:

三十二、贪心:

三十三、括号序列:


总结

提示:这里对文章进行总结:

💕💕💕

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1580316.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机硬件组成

计算机硬件组成 基本组成核心组件连接方式与总线架构与技术特殊组件总结脑图 基本组成 CPU: 执行指令和进行数据处理内存: 存储程序和数据&#xff0c;分为RAM和ROM主板: 连接所有硬件的平台&#xff0c;传输电子信号输入设备: 如键盘、鼠标等输出设备: 如显示器、打印机等 核…

Taro框架中的H5 模板基本搭建

1.H5 模板框架的搭建 一个h5 的基本框架的搭建 基础template 阿乐/H5 Taro 的基础模板

OpenHarmony实战:轻量系统STM32F407芯片移植案例

介绍基于STM32F407IGT6芯片在拓维信息Niobe407开发板上移植OpenHarmony LiteOS-M轻量系统&#xff0c;提供交通、工业领域开发板解决方案。 移植架构采用Board与SoC分离方案&#xff0c;使用arm gcc工具链Newlib C库&#xff0c;实现了lwip、littlefs、hdf等子系统及组件的适配…

论文学习D2UNet:用于地震图像超分辨率重建的双解码器U-Net

标题&#xff1a;&#xff1a;Dual Decoder U-Net for Seismic Image Super-Resolution Reconstruction ——D2UNet&#xff1a;用于地震图像超分辨率重建的双解码器U-Net 期刊&#xff1a;IEEE Transactions on Geoscience and Remote Sensing 摘要&#xff1a;从U-Net派生…

【Linux】进程的状态(运行、阻塞、挂起)详解,揭开孤儿进程和僵尸进程的面纱,一篇文章万字讲透!!!!进程的学习②

目录 1.进程排队 时间片 时间片的分配 结构体内存对齐 偏移量补充 对齐规则 为什么会有对齐 2.操作系统学科层面对进程状态的理解 2.1进程的状态理解 ①我们说所谓的状态就是一个整型变量&#xff0c;是task_struct中的一个整型变量 ②.状态决定了接下来的动作 2.2运行状态 2.…

R语言绘图 | 散点小提琴图

原文链接&#xff1a;R语言绘图 | 散点小提琴图 本期教程 写在前面 本期的图形来自发表在Nature期刊中的文章&#xff0c;这样的基础图形在日常分析中使用频率较高。 获得本期教程数据及代码&#xff0c;后台回复关键词&#xff1a;20240405 绘图 设置路径 setwd("You…

【数据结构】顺序表的动态分配(步骤代码详解)

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

算法设计与分析实验报告c++java实现(矩阵链连乘、投资问题、完全背包问题、旅行商问题、数字三角形)

一、 实验目的 1&#xff0e;加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握&#xff1b; 2&#xff0e;提高学生利用课堂所学知识解决实际问题的能力&#xff1b; 3&#xff0e;提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 用动态规…

防火墙操作!

当小编在Linux服务器上部署好程序以后&#xff0c;但是输入URL出现下述情况&#xff0c;原来是防火墙的原因&#xff01;&#xff01; 下面是一些防火墙操作&#xff01; 为保证系统安全&#xff0c;服务器的防火墙不建议关闭&#xff01;&#xff01; 但是&#xff0c;我们可…

idea(2023.1.3)配置全局Maven环境

问题来源一&#xff1a; 1、每次在下载依赖时&#xff0c;会遇到这样的报错信息&#xff0c;报错信息如下显示&#xff1a;sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid cert&#xff1b;百度结果是&#xff1a;通常表示IntelliJ IDEA …

第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组A-E题(go、java实现)

第十四届蓝桥杯大赛软件赛省赛C/C 大学 B 组 A题&#xff1a;日期统计B题&#xff1a;01串的熵C题&#xff1a;冶炼金属D题&#xff1a;飞机降落E题&#xff1a;接龙数列 A题&#xff1a;日期统计 直接遍历2023年每一天&#xff0c;看数组中是否有符合的 java的coding如下&…

【Shell】各种条件语句的使用——test语句、if语句、case语句

Shell条件语句的使用 条件语句 Shell条件语句的使用条件测试的语法字符串测试表达式整数二元比较操作符逻辑操作符 if的条件语句的语法if的嵌套case语句语法 条件测试的语法 语法1&#xff1a;test <测试表达式> 利用test命令进行条件测试表达式的方法。test命令与<测…

【操作系统】段描述符、全局描述符表和选择子

一、保护模式的内存寻址过程 与实模式不同的是&#xff0c;保护模式下内存段不再是简单地用段寄存器加载一下段基址然后乘以16位结合偏移地址得出实际要访问的内存地址&#xff0c;而是通过选择子在全局描述符表中找到对应的段描述符&#xff0c;CPU从段描述符中提取段基址&…

vscode 重命名很慢或失败 vscode renames are slow

网上问题&#xff0c; 插件问题&#xff08;我遇见的排除&#xff0c;不是&#xff09;被其他程序占用问题&#xff0c;&#xff08;我这边是这个&#xff09; 解决方案&#xff1a; 打开【资源管理器】&#xff0c;使用火绒 或其他软件&#xff0c;查看文件夹 or 文件 被哪个…

2024.4.9-day12-CSS 常用样式属性和字体图标

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 作业 <!DOCTYPE html> <html lang"zh-CN"><he…

C++进阶之路---何为智能指针?

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、为什么需要智能指针&#xff1f; 下面我们先分析一下下面这段程序有没有什么内存方面的问题&#xff1f;提示一下&am…

通过系统防火墙,禁用同网段主机互访

要通过系统防火墙禁止同网段主机之间的互访&#xff0c;您可以在Windows操作系统中使用高级防火墙规则来实现。以下是在Windows环境中创建一条规则以阻止本地同一子网内的计算机互相访问的基本步骤&#xff1a; 对于Windows防火墙&#xff08;适用于Windows 7至Windows 11&…

一文带你全面了解功能安全软件监控方案

引言&#xff1a;功能安全标准&#xff08;ISO26262 Part6&#xff09;提到了用于错误探测的安全机制&#xff0c;其中就有程序流监控&#xff0c;如图1所示&#xff1b;本文主要探讨在AUTOSAR CP以及AP的场景下&#xff0c;怎么实现程序流监控。 图1 ISO26262 Part6 一、CP场…

Android设备使用DS file远程访问群晖NAS管理本地文件

文章目录 1. 群晖安装Cpolar2. 创建TCP公网地址3. 远程访问群晖文件4. 固定TCP公网地址5. 固定TCP地址连接 DS file 是一个由群晖公司开发的文件管理应用程序&#xff0c;主要用于浏览、访问和管理存储在群晖NAS&#xff08;网络附加存储&#xff09;中的文件。这个应用程序具有…

JS--demo实现随机点名

逻辑就是通过点击事件得到数组里面的随机一个值&#xff0c;再把这个值给删除&#xff0c;当数组长度为1的时候&#xff0c;停止点名&#xff0c;用disabled属性让用户不能进行点击。 <!DOCTYPE html> <html lang"en"><head><meta charset&quo…