D. Unique Palindromes(回文串/构造)

news2024/11/24 1:18:27

题目

题意

给定字符串的长度,以及k个条件。
对于每个条件,给定x和c,表示原字符串的长度为x的前缀字符串,存在c个互不相同的回文子串。
原字符串由26个小写字母组成。

构造出长度为n,且满足上述k个条件的字符串。如果构造不出,输出NO;否则输出YES,并输出相应的字符串。

1<=k<=20,1<=n<=2*10^5, 3 <=x1<x2<…<xk=n, 3<=c1<=c2<=…<=ck<=10^9

比如给定以下数据,n=10,k=3,x = {4, 6, 10}, c = {4, 5, 8}

10 3
4 6 10
4 5 8

符合条件的字符串为abcbcacbab。

  • 对于前缀长度为4的子字符串abcb,存在 回文子串a,b,c,bcb,因此回文子串数量为4;
  • 对于前缀长度为6的子字符串abcbca,存在 回文子串a,b,c,bcb,cbc,因此回文子串数量为5;
  • 对于前缀长度为10的子字符串abcbcacbab,存在 回文子串a,b,c,bcb,cbc,cac,bcacb,bab,因此回文子串数量为8;

思路

规律1

长度<=3的字符串,无论字母构造,它的回文子串的个数为它长度。
以n=3为例,它的构造方式有以下几种。

aaa
aab
aba
abc

我们发现,上述任一一个字符串,回文子串的个数都为3。

规律2

对于长度>3的前缀子串(假设长度为len),它的回文子串的个数,相比长度为len-1的前缀子串的回文子串数,最多增加1。
证明:假设 长度为len的前缀子串新增的回文串,最大长度为mx,那么表示s[len-mx+1, len-mx,…,len]是回文串,假设存在另一个新增的回文串,长度为mx2 < mx,那么表示s[len-mx2+1, len-mx2,…,len]是回文串。又因为s[len-mx+1, len-mx,…,len]是回文串,可以推出s[len-mx+1, len-mx,…,len-(mx-mx2)]也是回文串。因此s[len-mx2+1, len-mx2,…,len]不是新增的回文串,矛盾。
在这里插入图片描述

推论

结合规律1和规律2,我们可以得出结论,对于长度len>3的字符串,它的回文子串的个数,不超过它的长度len本身。
因此,有以下结论

  • 如果c>x,那么显然构造不出来;
  • 以及,如果c[i]-c[i-1]>x[i]-x[i-1],也构造不出来。

构造方法

构造不出来的情况考虑好后,接下来考虑构造字符串。
主要利用以下两个结论:

  • 每新增一个新的字符,必定增加一个回文串。如abc -> abcd
  • 对于一个字符,如果重复该字符,必定增加一个回文串。如abb -> abbb

又因为k最大只取20,26个小写字母够用了。
如果未使用字符没用完,则优先使用 未使用字符;
否则使用 “重复字符”的方式,为了避免重复字符的方法,被同一个字符重复使用,导致新增回文串失败,我们用完一个字符,后边就不再使用了。
特殊情况考虑,如果需要重复的字符已经被删掉了,我们需要考虑下复用 字符已经被删除 的场景。

其他的字符,我们就用循环节 填充即可。

详见代码。
当时做题时卡住的样例,也附在代码后边了。

PS:构造题真不擅长orz

代码

#include<string>
#include<iostream>
#include<cmath>
#include<map>
using namespace std;
#define ll long long
const int maxn = 200010;

int n, k;
int c[maxn], x[maxn];
 
void solve() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= k; ++i) {
		scanf("%d", &x[i]);
		--x[i];
	}
	for (int i = 1; i <= k; ++i) {
		scanf("%d", &c[i]);
	}
	bool flag = true;
	x[0] = -1;
	c[0] = 0;
	for (int i = 1; i <= k; ++i) { // 无解的场景
		if (c[i] > x[i] + 1 || c[i] < 3 || (c[i] - c[i-1]) > (x[i] - x[i-1])) {
			flag = false;
			break;
		}
	}
	if (!flag) {
		printf("NO\n");
		return;
	}
	string ans = "";
	string res = ""; // 用于构造循环节的字符串
	char nxt = 'a';
	int pos = 0, mod;
	for (int i = 1; i <= k; ++i) {
		int tot = x[i] - x[i-1]; // 需要添加的字符总数
		int add = c[i] - c[i-1]; // 需要新增的回文字符串 数量
		int left = tot - add; // 需要新增的字符,且不 增加 回文字符串
		
		bool new_flag = false;
		if (add && nxt <= 'z') { // 是否存在还没有使用的字符 & 需要添加新增回文字符串 数量
			new_flag = true;
			pos = 0; // 重置 循环节 初始下标,防止出现 回文串
		}
		while (add && nxt <= 'z') { // 需要新增 回文 数,且还有 未使用字符
			res += nxt;
			ans += nxt;
			++nxt;
			--add;
		} 
		mod = res.size();
		// 重置循环节后, 需要防止 出现 回文串,如 ada 这种
		if (new_flag && ans.length() > 2 && ans[ans.length()-2] == res[pos]) {
			pos = (pos + 1) % mod; 
		}
		while (left--) { // 添加循环节字符,不增加 回文 数
			ans += res[pos];
			pos = (pos + 1) % mod; 
		}
		
		if (add) { // 需要添加 回文 数,且 未使用字符已经用完的场景
			int last_pos = (pos - 1 + mod) % mod; // 取上一个字符
			if (res[last_pos] == ans.back()) { // 上一个字符 等于 当前字符串的 末尾字符,则先添加,后删除
				pos = last_pos;
				while (add--) {
					ans += res[pos];
				} 
				res.erase(res.begin() + pos);
				if (pos == res.length()) { // update pos
					pos = 0;
				}
			} else { // 上一个字符 不等于 当前字符串的 末尾字符,说明该字符已经不存在于res,直接复用ans.back()
				char c = ans.back();
				while (add--) {
					ans += c;
				}
			}
			
		}
	}
	printf("YES\n%s\n", ans.c_str());
	
} 
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		solve();
	}
}
/*
3:
aaa
aab
aba
abc

99
100 2
32 35
32 33

8 6
3 4 5 6 7 8
3 3 3 4 4 4

6 4
3 4 5 6
3 3 4 4

48 17
8 12 13 15 17 19 20 22 24 26 27 38 40 43 46 47 48
5 7 7 9 10 11 12 13 15 17 18 25 27 29 31 32 32

*/

同名GZH:对方正在debug,欢迎关注~~

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

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

相关文章

不黑艺术学社京藏行——参观五台山孙溟㠭为五台山红英师治印

不黑学社社长孙溟㠭先生与五台山菩萨顶主事红英师 不黑学社京藏行&#xff0c;路经五台把佛拜。 巍巍五台清凉境&#xff0c;参访伊始菩萨顶。 感恩“天珠”刘诗语&#xff0c;芬芳佛语满香华。 感恩慈悲红英师&#xff0c;带众参拜大白塔。 菩萨顶上如意宝&#xff0c;莲…

springboot+vue口腔管理平台(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的口腔管理平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

微服务---分布式多级缓存集群实现方案(Caffeine+redis+nginx本地缓存+Canal数据同步)

分布式多级缓存集群实现方案 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; •请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的…

DJ5-1/2 输入输出系统(第一节课)

目录 5.1 I/O 系统的功能、模型和接口 5.1.1 I/O 系统的基本功能 5.1.2 I/O 系统的层次结构和模型 5.1.3 I/O 系统接口 5.2 I/O 设备和设备控制器 5.2.1 I/O 设备 5.2.2 设备控制器 5.2.3 I/O 通道 5.2.4 总线系统 5.1 I/O 系统的功能、模型和接口 5.1.1 …

Python进阶篇(五)-- 邮件客户端实现与电子邮件发送

1 SMTP 通过完成本实验&#xff0c;我们将更加了解SMTP协议。还将学到使用Python实现标准协议的经验。 主要任务是开发一个简单的邮件客户端&#xff0c;将邮件发送给任意收件人。客户端将需要连接到邮件服务器&#xff0c;使用SMTP协议与邮件服务器进行对话&#xff0c;并向邮…

【P5】JMeter HTTP Cookie管理器

文章目录 一、测试网站二、Cookie 设置规则2.1、无配置元件时&#xff0c;Cookie 不会自动设置&#xff08;与线程组设置无关&#xff09;2.2、有配置元件&#xff0c;不选任何参数时&#xff0c;Cookie 自动设置&#xff08;与线程组设置无关&#xff09;2.3、有配置元件&…

【iOS KVO(上)实现过程】

前言 KVO 也适用于传值&#xff0c;在之前的学习只是学习了KVO的传值&#xff0c;今天详细学习 监听和实现 源码放在下一节学习 1.1 KVO KVO&#xff08;Key-Value Observing&#xff09;是Objective-C语言中一种观察者模式的实现&#xff0c;可以用来监听对象属性值的变化…

Kafka基础概念介绍

背景 Kafka是我们项目用的最多的消息中间件&#xff0c;但里面也有很多存在的问题&#xff0c;如重复消费、带宽瓶颈、部分分区消费不下来的异常场景。 重复消费问题有些让人头疼&#xff08;reblance导致offset提交失败&#xff09;&#xff0c;这里会持续更新&#xff08;基…

UML简介与类图详解

1 UML简介 1.1 UML是什么 UML&#xff0c;全称为Unified Model Language&#xff0c;即统一建模语言&#xff0c;是由一整套图表组成的&#xff0c;为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言。UML 代表了一组最佳工程实践&#xff0c;这些实践已被证明在…

【路径规划】基于哈里斯鹰优化算法的栅格法路径规划 机器人路径规划【Matlab代码#20】

文章目录 1. 原始HHO算法2. 机器人路径规划环境创建3. 路径规划模型建立4. 部分代码展示5. 仿真结果展示6. 资源获取方式 1. 原始HHO算法 详细介绍此处略&#xff0c;可参考HHO算法介绍 2. 机器人路径规划环境创建 对机器人工作空间的进行环境建模是机器人路径规划研究的重要…

【电源专题】案例:拆一个早期用的万能充看看内部状况

说到万能充,可能存在80/90后的记忆里。以前手机都可以更换电池的,所有往往都是买两块,一块在手机内部使用,另一块在万能充充电。 万能充的外观也是大同小异的,从网上找了一些图片: 这东西现在日常生活已经都看不到了,关键因素之一应该是现在的手机电池都是不可拆…

多维图像去噪方法研究

一、背景介绍 由于传感器技术的快速发展&#xff0c;高光谱&#xff08;HS&#xff09;遥感&#xff08;RS&#xff09;成像为飞机等数据采集设备远距离观测和分析地球表面提供了大量的空间和光谱信息&#xff0c;航天器和卫星。 HS RS 技术的最新进展甚至革命为实现各种应用的…

【ONE·C++ || set和map(一)】

总言 主要介绍set和map的基本框架和使用 文章目录 总言1、部分接口介绍和使用举例1.1、序列式容器和关联式容器、键值对1.1.2、pair键值对 1.2、set基本介绍1.2.1、set::set、遍历1.2.2、set::insert、set::erase、set::find1.2.3、set::count、set::lower_bound、set::upper_…

数据结构与算法基础(青岛大学-王卓)(1)

士别三日当刮目相待&#xff0c;不好意思鸽了好久了&#xff0c;因为学习的时间不连续&#xff0c;所以我一直攒着&#xff0c;我又回来继续更新了 没有继续学习浙大的数据结构了&#xff0c;对比了青岛大学的王老师的这个教程我觉得更适合我一些&#xff0c;更入门&#xff0…

【Spring篇】Spring整合

&#x1f353;系列专栏:Spring系列专栏 &#x1f349;个人主页:个人主页 目录 一、Spring整合 1.Spring整合Mybatis思路分析 1.环境准备 2.整合思路分析 2.Spring整合Mybatis 3.Spring整合Junit 1.环境准备 2.整合Junit步骤 二、图书推荐 1.《元宇宙Ⅱ&#xff1a;图…

Ubuntu安装MySQL

一.安装MySQL服务器 安装MySQL服务器&#xff1a; apt-get install mysql-server 对MySQL进行初始化&#xff0c;设置密码&#xff1a; mysql_secure_installation 注意&#xff0c;这里要设置密码的最低长度为8位&#xff0c;如果你设的密码小于8位&#xff0c;则会提示&am…

有趣工具合集小程序-做你的小树洞小程序

有趣工具合集小程序-做你的小树洞 今天闲来无事&#xff0c;发现了一个有趣的小程序-做你的小树洞&#xff0c;包含ChatGpt小机器人、抛硬币、手持弹幕、亲戚计算器、藏头诗、唐诗三百首、歇后语以及猜谜语等功能 小程序总体界面是这样的 1.藏头诗 这个小程序里边有很多有趣…

Redis的哨兵和集群模式

哨兵模式# 哨兵模式是redis高可用的实现方式之一 使用一个或者多个哨兵(Sentinel)实例组成的系统&#xff0c;对redis节点进行监控&#xff0c;在主节点出现故障的情况下&#xff0c;能将从节点中的一个升级为主节点&#xff0c;进行故障转义&#xff0c;保证系统的可用性。 哨…

【Qt5】多线程串口

文章目录 原版代码工程增加QCustomplot实时画图的源码工程源码 原版代码工程 源码下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/15pWzadPwOx_OfJGtvL-MjA 提取码&#xff1a;lief –来自百度网盘超级会员V5的分享 增加QCustomplot实时画图的源码工程 源码&…

【Mybatis】增删改查

1.添加相应的jar包 2.创建持久化类 在src目录下创建一个名为com.mybatis.po的包 创建持久化类MyUser,包含三个属性&#xff08;uid,uname,usex) package com.mybatis.po; /***springtest数据库中user表的持久化类*/ public class MyUser {private Integer uid;//主键private…