题意:
给定一个长度为 $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$ 后的字符串输出。
代码(不喜勿喷)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #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; }
|