Codeforces Round 868 (Div. 2) D

文章介绍了一种解决CodeforcesProblemD问题的算法。给定长度为n的字符串和一系列条件(每个位置的字符数a[i]和不同回文子串数b[i]),任务是判断能否构造这样的字符串。当a[i]-a[i-1]<b[i]-b[i-1]时,答案为NO。否则,通过选择特定字母组合并重复添加新字母来构造字符串,确保回文子串数量增加且不重复。提供的C++代码实现了解决方案。
摘要由CSDN通过智能技术生成

题目链接:Problem - D - Codeforces

输入样例:

7
10 2
5 10
5 6
3 1
3
3
4 2
3 4
3 3
4 2
3 4
3 4
4 1
4
5
10 3
4 6 10
4 5 8
10 4
4 6 7 10
4 5 7 8

输出样例:

YES
abcbbcabcb
YES
foo
YES
ayda
YES
wada
NO
YES
abcbcacbab
NO

题意:要求构造出一个长度为n,满足k个条件的字符串。条件为字符串的前a[i]个字符组成的字符串中有b[i]个不同的回文子串。

思路:

设a为字符的个数,b为回文数的个数

1. NO的情况:多一个字符最多多构成一个回文,所以当a[i] - a[i - 1] < b[i] - b[i - 1]时,输出NO

2. 构造这个字符串的主要思想:

        2.1 首先选择三个字母作为开头(题目里已经明确种类大于等于3),同时这三个字母也是接下来减少回文子串的关键,为什么不是两个字母呢?因为我们是要拿这个三个字母来减少回文子串,即这几个字符组成的串不能构成除单个字符以外的回文子串,而ababab就会构成回文子串,abcabc就不会。

        2.2 每次操作都用不同的字母重复的添加在字符串里,n个重复的字母构成了n个回文子串,保证了回文子串的增加,不重复的字母保证了每次增加的回文子串都不一样。数据的条件数不超过20,加上开头用到字母3个,26个字母完全够用。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int a[N], b[N];
void solve(){
	int n, k;  cin >> n >> k;
	for(int i = 1; i <= k; i++)  cin >> a[i];
	for(int i = 1; i <= k; i++)  cin >> b[i];
	string s = "abc", ans = "abc";
	int cnt = 3, mk = 0;
	a[0] = b[0] = 3;
	for(int i = 1; i <= k; i++){
		int x = a[i] - a[i - 1];
		int y = b[i] - b[i - 1];
		if(y > x){
			printf("NO\n");
			return ;
		}
		if(y){
			for(int i = 0; i < y; i++)  ans.push_back('a' + cnt);
			cnt++;
		}
		for(int i = 0; i < x - y; i++){
			ans.push_back(s[mk]);
			mk = (mk + 1) % 3;
		}
	}
	cout << "YES\n" << ans << "\n";
}

int main(){
//	ios::sync_with_stdio(false);
	cin.tie(0);  cout.tie(0);
	int tt = 1;
	cin >> tt;
	while(tt--){
		solve();
	}
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值