Loading

[ABC314D] LOWER 题解

题意:

给定一个长度为 \(n\) 的字符串,有 \(m\) 次操作,每次操作给定两个整数 \(t\)\(x\),以及一个字符 \(c\),满足以下操作:

\(\hspace{1em}\bullet\)\(t\)\(1\),则将字符串中的第 \(x\) 个字符更改为 \(c\)

\(\hspace{1em}\bullet\)\(t\)\(2\),则将字符串中的所有大写字母变为小写字母

\(\hspace{1em}\bullet\)\(t\)\(3\),则将字符串中的所有小写字母变为大写字母

求最后的字符串

思路:

针对操作 \(1\),直接更改即可,但是由于这个操作可能会改变原有字符串的性质(全部是大写\全部是小写),所以可以维护一个 \(map\),用来判断的是:在上一次使用操作 \(2、3\) 后,字符串中的哪些位置又因为操作 \(1\) 而更改。

针对操作 \(2、3\),因为这两个操作之后,整个字符串要么全为大写,要么全为小写,所以用两个 \(bool\)\(pd\)\(px\) 存储即可。

最后输出的时候,如果 \(pd\)\(px\) 中有一个为一,这意味着最后一个操作不为操作 \(1\),所以直接按大小写输出即可。

否则,意味着最后一步的操作必定为操作 \(1\),字符串在改变大小写后又更改了,所以只需判断 \(map\) 中当前的位置是否更改,更改的话输出原字符串,否则按最后一个操作 \(2、3\) 后的字符串输出。

代码(不喜勿喷)

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
template<typename P>
inline void read(P &x){
   	P res=0,f=1;
   	char ch=getchar();
   	while(ch<'0' || ch>'9'){
   		if(ch=='-') f=-1;
   		ch=getchar();
   	}
   	while(ch>='0' && ch<='9'){
   		res=res*10+ch-'0';
   		ch=getchar();
	}
	x=res*f;
}
int T=1;
int n;
int Q;
char s[500010];
signed main(){
	read(n);
	for(int i=1;i<=n;++i) cin>>s[i];
	read(Q);
	int op,x;
	char y;
	int sumc=0;
	bool qd=0,qx=0;
	map<int,bool> q;
	for(int i=1;i<=Q;++i){
		read(op),read(x);
		cin>>y;
		if(op==1){
			s[x]=y;
			q[x]=1;
		}
		else if(op==2){
			qx=1,qd=0;
			q.clear();
		}
		else{
			qd=1,qx=0;
			q.clear();
		};
	}
	if(qx==1){
		for(int i=1;i<=n;++i){
			if(q[i]==0){
				if(s[i]>='A' && s[i]<='Z') cout<<char(s[i]+32);
				else cout<<s[i];
			}
			else cout<<s[i];
		}
		cout<<endl;
	}
	else if(qd==1){
		for(int i=1;i<=n;++i){
			if(q[i]==0){
				if(s[i]>='a' && s[i]<='z') cout<<char(s[i]-32);
				else cout<<s[i];
			}
			else cout<<s[i];
		}
		cout<<endl;
	}
	else{
		for(int i=1;i<=n;++i){
			cout<<s[i];
		}
		cout<<endl;
	}
	return 0;
}


posted @ 2024-07-25 15:00  God_Max_Me  阅读(3)  评论(0编辑  收藏  举报