首页 > 其他分享 >QOJ 2486 Build the String

QOJ 2486 Build the String

时间:2024-01-21 15:55:22浏览次数:32  
标签:String 2486 text texttt back len int ans QOJ

考虑当字符串全为 \(\texttt{b}\) 时,可以通过 \(\text{copy}\) \(n - 1\) 次再 \(\text{fuse}\) \(n\) 次。
这启发从连续段来做,先按顺序构造出一个个连续段,最后 \(\text{fuse}\) 合为这个串。

若第一个连续段为 \(\texttt{a}\),则可以通过 \(\text{swap}\) 事先交换 \(\texttt{ab}\),于是就统一为了 \(\texttt{b}\) 开头。

令连续段个数为 \(m\),第 \(i\) 段的长度为 \(len_i\)。
对于前 \(m - 2\) 段,因为当前连续段对应的字符在之后还要用到,所以需要多留一个这个字符,\(\text{copy}\) \(len_i\) 次,\(\text{fuse}\) \(len_i - 1\) 次。
此时这个栈顶是个 \(\texttt{a, b, bbbbb}\) 的形式,而下一个连续段需要的是 \(\texttt{a}\),要放在开头,下下个连续段需要 \(\texttt{b}\),要放在 \(\texttt{a}\) 后面像现在这样操作,所以 \(\text{swap, roll}\) 变为 \(\texttt{bbbbb, b, a}\) 的形式,这里有个剪枝,当 \(len_i = 1\) 时 \(\text{swap}\) 并没有效果,可以删去。
对于第 \(m - 1\) 段,其对应的字符后面已经不用了,可以直接合并上,\(\text{copy}\) \(len_{m - 1} - 1\) 次,\(\text{fuse}\) \(len_{m - 1} - 1\) 次,那么接下来直接 \(\text{swap}\) 即可把第 \(m\) 段的字符放在栈顶。
对于第 \(m\) 段类似 \(m - 1\) 段,\(\text{copy}\) \(len_{m} - 1\) 次,\(\text{fuse}\) \(len_{m} - 1\) 次。
最后考虑把这 \(m\) 段合并起来,\(\text{fuse}\) \(m - 1\) 次。

对于 \(m = 1\) 次数显然为 \([s_1 = \texttt{a}] + 2n - 1\)。
对于 \(m\ge 2\) 总的次数为 \([s_1 = \texttt{a}] + 2n + \sum\limits_{i = 1}^{m - 2}[len_i\ge 2] + m - 4\),最坏情况即 \(s_1 = \texttt{a}, len_i = 1 + [i\le m - 2]\) 时总次数为 \(1 + 2n + \frac{n}{2} - 1 + \frac{n}{2} + 1 - 4 = 3n - 3\)。

#include<bits/stdc++.h>
const int maxn = 1e5 + 10;
char s[maxn];
int len[maxn];
std::vector<std::string> ans;
int main() {
	scanf("%s", s + 1);
	int n = strlen(s + 1);
	if (s[1] == 'a') {
		ans.push_back("swap");
		for (int i = 1; i <= n; i++) s[i] ^= 'a' ^ 'b';
	}
	int m = 0;
	for (int l = 1, r; l <= n; l = r) {
		for (r = l; r <= n && s[r] == s[l]; r++);
		len[++m] = r - l;
	}
	if (m == 1) {
		for (int i = 1; i < n; i++) ans.push_back("copy");
		for (int i = 1; i < n; i++) ans.push_back("fuse");
	} else {
		for (int i = 1; i <= m - 2; i++) {
			for (int j = 1; j <= len[i]; j++) ans.push_back("copy");
			for (int j = 1; j < len[i]; j++) ans.push_back("fuse");
			if (len[i] > 1) ans.push_back("swap");
			ans.push_back("roll");
		}
		for (int i = 1; i < len[m - 1]; i++) ans.push_back("copy");
		for (int i = 1; i < len[m - 1]; i++) ans.push_back("fuse");
		ans.push_back("swap");
		for (int i = 1; i < len[m]; i++) ans.push_back("copy");
		for (int i = 1; i < len[m]; i++) ans.push_back("fuse");
		for (int i = 1; i < m; i++) ans.push_back("fuse");
	}
	printf("%zu\n", ans.size());
	for (std::string a : ans) std::cout << a << '\n';
	return 0;
}

标签:String,2486,text,texttt,back,len,int,ans,QOJ
From: https://www.cnblogs.com/lhzawa/p/17977935

相关文章

  • QOJ 4996 Icy Itinerary
    先转化题目条件。发现把\(n\)个点划分为\(2\)个点集,满足其中一个点集存在哈密顿路,另一个点集在补图中存在哈密顿路和原问题是等价的。令直接存在哈密顿路的点集为\(X\),其路径端点分别为\(S_X,T_X\);补图中存在哈密顿路的点集为\(Y\),路径端点分别为\(S_Y,T_Y\);考虑\(......
  • StringGrid1单元格内绘图
     varRect:Trect;beginRect:=bg.CellRect(4,3);bg.Canvas.Brush.Color:=clwhite;bg.Canvas.FillRect(rect);bg.Canvas.Draw(rect.Left+trunc((rect.Right-rect.Left-tx2.Width)/2)//单元格水平居中,rect.Top+tr......
  • 21String类的实现
    String类的实现//#include<string>#include<iostream>usingnamespacestd;classString{private: char*_pstr; friendStringoperator+(constString&s1,constString&s2); friendostream&operator<<(ostream&out,constS......
  • 22String字符串和vector对象的迭代器iterator实现
    String字符串对象的迭代器iterator实现泛型算法参数接收的都是迭代器泛型算法是一组全局的函数,适用于所有容器基于第二点,泛型算法有一套方法可以统一地遍历所有容器的元素classString{public: //嵌套定义iterator类 classiterator { private: char*_p;//没有用......
  • CF1830C Hyperregular Bracket Strings
    HyperregularBracketStringsLuoguCF1830C题目描述给定一个数\(n\)和\(k\)个区间\(\left[l_i,r_i\right]\in[1,n]\)。我们定义,对于一个长度为\(n\)的,仅由(和)组成的合法括号序列,如果它的每一个区间\(\left[l_i,r_i\right]\)内的子串都是合法括号序列,那么这个......
  • 无涯教程-MATLAB - 字符串(Strings)
    在MATLAB中创建字符串非常简单,实际上,我们已经使用了很多次。例如,您在命令提示符下键入以下内容-my_string='LearnfkPoint'MATLAB将执行上述语句并返回以下输出-my_string=LearnfkPointMATLAB将所有变量视为数组,而字符串则视为字符数组,让我们使用whos命令检查上面创建的变......
  • 一文看完String的前世今生,内容有点多,请耐心看完!
    写在开头String字符串作为一种引用类型,在Java中的地位举足轻重,也是代码中出现频率最高的一种数据结构,因此,我们需要像分析Object一样,将String作为一个topic,单独拿出来总结,这里面涉及到字符串的不可变性,字符串拼接、存储、比较、截取以及StringBuffer,StringBuilder区别等。String......
  • string reversal using stack【1月19日学习笔记】
    点击查看代码//stringreversalusingstack#include<iostream>#include<stack>//stackfromstandardtemplatelibrary(STL)usingnamespacestd;voidreverse(char*c,intn){ stack<char>S; for(inti=0;i<n;i++){ S.push(c[i]);//st......
  • VBA001 String、Space関数
    VBAで全角スペースを指定数追加する(String)VBAで半角スペースを指定数追加する(Space)1,String関数の使用方法構文String(Number,Character)説明Number:文字をいくつ並べるのかを整数値で指定します。Character:文字の文字コード、または文字列を指定します。この文字が引数Nu......
  • StringBuilder 线程不安全,到底哪里不安全?
    StringBuilder线程不安全,到底哪里不安全?在Java中,字符串拼接是一个非常常见的操作,而对于频繁变动的字符串内容,使用StringBuilder是一个性能优化的选择。但是,StringBuilder在使用上存在一个很大的限制,它是线程不安全的。在多线程环境下,不正确的使用StringBuilder可能导致数据不一......