AtCoder Beginner Contest 158 D - String Formation(字符串拼接)

题目链接:https://atcoder.jp/contests/abc158/tasks/abc158_d

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement

Takahashi has a string S consisting of lowercase English letters.

Starting with this string, he will produce a new one in the procedure given as follows.

The procedure consists of Q operations. In Operation ii (1≤i≤Q), an integer Tiis provided, which means the following:

  • If Ti=1Ti=1: reverse the string SS.

  • If Ti=2Ti=2: An integer FiFi and a lowercase English letter CiCi are additionally provided.

    • If Fi=1Fi=1 : Add CiCi to the beginning of the string SS.
    • If Fi=2Fi=2 : Add CiCi to the end of the string SS.

Help Takahashi by finding the final string that results from the procedure.

Constraints

  • 1≤|S|≤105
  • SS consists of lowercase English letters.
  • 1≤Q≤2×105
  • Ti=1or 2
  • Fi=1 or 2, if provided.
  • Ci is a lowercase English letter, if provided.

Input

Input is given from Standard Input in the following format:

SS
QQ
Query
::
Query

In the 3-rd through the (Q+2)-th lines, QueryiQueryi is one of the following:

11

which means Ti=1, and:

22 FCi

which means Ti=2.

Output

Print the resulting string.


Sample Input 1 

 

a
4
2 1 p
1
2 2 c
1

Sample Output 1 

 

cpa

There will be Q=4 operations. Initially, S is a.

  • Operation 1: Add p at the beginning of S. S becomes pa.

  • Operation 2: Reverse S. S becomes ap.

  • Operation 3: Add c at the end of S. S becomes apc.

  • Operation 4: Reverse S. S becomes cpa.

Thus, the resulting string is cpa.


Sample Input 2 Copy

a
6
2 2 a
2 1 b
1
2 2 c
1
1

Sample Output 2 Copy

aabc

There will be Q=6Q=6 operations. Initially, SS is a.

  • Operation 11: S becomes aa.

  • Operation 22: S becomes baa.

  • Operation 33: S becomes aab.

  • Operation 44: S becomes aabc.

  • Operation 55: S becomes cbaa.

  • Operation 66: S becomes aabc.

Thus, the resulting string is aabc.


Sample Input 3 Copy

y
1
2 1 x

Sample Output 3 Copy

xy

题解写了很多,都是废话。。。。。

直接看大佬代码:

#include
using namespace std;
int main()
{
	string s;
	cin>>s;
	int Q;
	cin>>Q;
	string T;
	for(int i=1;i<=Q;i++)
	{
		int t;
		cin>>t;
		if(t==1)
		{
			swap(s,T);
		}
		if(t==2)
		{
			int f;
			char c;
			cin>>f>>c;
			if(f==1) T.push_back(c);
			if(f==2) s.push_back(c);
		}
	}
	reverse(T.begin(),T.end());
	cout<

不知道其他大佬怎么写的,我用string的字符串拼接写的,结果超时;超时的原因我总结一下有两点:

  1. 每一次字符串反转超时;
  2. 字符串拼接超时;

One.

解决第一个问题的关键在于不能每一次都对字符串进行翻转,可以用cnt记录反转操作出现的次数,当cnt为偶数时,说明字符串没有进行反转,则进行添加操作时,可以正常进行;当cnt为奇数时,说明字符串进行了一次反转,那么进行当前添加操作时,应该按相反的操作进行;比如字符串abcd,常规操作:将他进行三次反转之后是,dcba,我在开头加上e,结尾加上f,变成edcbaf;另一种操作,cnt为偶数,则执行e加到开头这个操作时,要按相反的来,同理,f也相反,那就变成fabcde,由于cnt为奇数,抵消之后还剩一次反转操作,那么进行翻转得到edcba;并且再最后输出的时候要把后缀变前缀,中间反转,前缀变后缀

上面可能说的太罗嗦了 ,我举个简单例子吧;

原始字符串:abcd   执行开头加e,反转,结尾加f,反转,开头加m,结尾加n,反转;(cnt为执行当前操作之前反转的次数)

开头加e,cnt为0,e加入前缀;(此时前缀为e)

结尾加f,cnt为1,f加入前缀;(此时前缀为fe)

开头加m,cnt为2,m加入前缀;(此时前缀为mfe)

结尾加n,cnt为2,n加入后缀;(此时后缀为n)

由于最后cnt为3,所以输出的时候要反转,先输出反转后缀n,然后中间反转dcba,前缀反转efm;

over....

Two.

然后就是字符串的拼接,

两种拼接方式:

s+=ss;        //这种拼接为引用拼接

s=s+ss;   //重新生成了一个对象的拼接

前者比后者快;

当你把当前这个字符ss加到开头的操作是s=ss+s,加到结尾的操作是s+=ss;由于原字符串s长度比较大的原因,会造成拼接效率下降,所以这里如果用原字符串进行拼接,不妥;可以定义一个前缀字符串a保存放在开头的字符,一个后缀字符串b保存放在结尾的字符;这样拼接的时候字符串长度大大下降,效率大大提升;

(可能这一题并没有卡这个地方,也许有别的更高效便捷的做法,欢迎大佬们指出qaq~)

#include 
using namespace std;
typedef long long ll;

int main()
{
	ios::sync_with_stdio(false);
	string s,ss;
	string a,b;
	cin>>s;
	int q,cnt=0;
	cin >>q;
	while(q--)
	{
		int t;
		cin >>t;
		if(t==1) cnt++;
		else
		{
			int f;
			cin >>f>>ss;
			if(f==1)
			{
				if(cnt%2) b+=ss;
				else a=ss+a; 
			}
			else
			{
				if(cnt%2) a=ss+a;
				else b+=ss;
			}
		}
	}
	int x=a.size(),y=b.size(),z=s.size();
	if(cnt%2)
	{
		
		for(int i=y-1;i>=0;i--) cout <=0;i--) cout <=0;i--) cout <

 

你可能感兴趣的:(c++学习(STL),训练)