CF2111E Changing the String

题意

给定一个仅由 \(a,b,c\) 组成的字符串 \(S\)。

给出 \(q\) 次操作。每个操作 \((x,y)\) 表示将 \(S\) 中任意一个 \(x\) 换成 \(y\),可以不换

求按给定的顺序执行所有操作后得到字典序最小的字符串。

题解

简单贪心。

首先越前面优先级越高,所以从前往后考虑,能换则换。

下面考虑如何操作:

  • 对于 \(a\),不用换,所以 \(a \rightarrow b\) 和 \(a \rightarrow c\) 没用。
  • 对于 \(b\),考虑 \(b\) 换成 \(a\),尝试用 \(b \rightarrow a\) 或者 \(b \rightarrow c \ + c \rightarrow a\),两者无优先顺序。
  • 对于 \(c\),
    1. 先考虑将 \(c\) 换成 \(a\),尝试用 \(c \rightarrow a\) 或者 \(c \rightarrow b \ + \ b \rightarrow a\),两者无优先顺序。
    2. 再考虑将 \(c\) 换成 \(b\),尝试用 \(c \rightarrow b\)。

注意复合操作时,如 \(c \rightarrow b \ + \ b \rightarrow a\) 要保证 \(c \rightarrow b\) 在 \(b \rightarrow a\) 的前面,并且要确保找到第一个位置大于 \(c \rightarrow b\) 的 \(b \rightarrow a\),保证后续能用到的 \(b \rightarrow a\) 操作尽可能靠后,用 upper_bound 实现。

实现时,用 set 维护每种操作的位置,用 insert 插入,erase 删除使用过了的操作,upper_bound 满足复合操作的需求。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,q;
set<int> ba,bc,cb,ca;//b->a b->c c->b c->a
char s[N]; void solve(){
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>s[i];
ba.clear(),bc.clear(),cb.clear(),ca.clear();//多测清空
for(int i=1;i<=q;i++){
char x,y;
cin>>x>>y;
if(x=='b'){
if(y=='a') ba.insert(i);
else if(y=='c') bc.insert(i);
}else if(x=='c'){
if(y=='a') ca.insert(i);
else if(y=='b') cb.insert(i);
}
}
for(int i=1;i<=n;i++){
if(s[i]=='b'){
if(!ba.empty()){
s[i]='a';
ba.erase(*ba.begin());
}else{
if(!bc.empty()&&!ca.empty()){
int BC=*bc.begin();
auto CA=ca.upper_bound(BC);
if(CA==ca.end()) continue;
s[i]='a';
bc.erase(BC);
ca.erase(*CA);
}
}
}else if(s[i]=='c'){
if(!ca.empty()){
s[i]='a';
ca.erase(*ca.begin());
}else{
if(!cb.empty()){
if(!ba.empty()){
int CB=*cb.begin();
auto BA=ba.upper_bound(CB);
if(BA==ba.end()){
s[i]='b';
cb.erase(CB);
}else{
s[i]='a';
cb.erase(CB);
ba.erase(*BA);
}
}else{
s[i]='b';
cb.erase(*cb.begin());
}
}
}
}
}
for(int i=1;i<=n;i++) cout<<s[i];
cout<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T; cin>>T;
while(T--) solve();
return 0;
}

CF2111E Changing the String的更多相关文章

  1. Codeforces 56D Changing a String 编辑距离 记忆dp

    主题链接:点击打开链接 编辑距离.,== 一边dp虽然录制前体累,,依然是dp #include<iostream> #include<cstdio> #include< ...

  2. Codeforces 56D Changing a String

    http://codeforces.com/contest/56/problem/D 题目大意: 一个字符串变为目标字符串,可以执行插入,置换和删除3种操作,求最少操作数. 思路:dp[i][j]代表 ...

  3. Codeforces 56D Changing a String (DP)

    题意:你可以对字符串s进行3种操作: 1,在pos位置插入字符ch. 2,删除pos位置的字符. 3,替换pos位置的字符为ch. 问最少需要多少次操作可以把字符s变成字符s1? 思路: 设dp[i] ...

  4. Why string is immutable in Java ?

    This is an old yet still popular question. There are multiple reasons that String is designed to be ...

  5. Why String is immutable in Java ?--reference

    String is an immutable class in Java. An immutable class is simply a class whose instances cannot be ...

  6. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  7. V8Sharp的中文乱码问题解决

    V8是一个开源的javascript引擎,到现在为止堪称为是性能最好最稳定的javascript.因此还诞生了一个基于此引擎的服务端开发框架:Node.js.由此可见此引擎的牛逼之处.由于打算在后续项 ...

  8. [翻译] GONMarkupParser

    GONMarkupParser https://github.com/nicolasgoutaland/GONMarkupParser NSString *inputText = @"Sim ...

  9. InstallShield Clone dialog

    Browse to Dialogs view, right-click an existing dialog, click Clone and rename the cloned dialog. Wh ...

  10. How to distinguish between strings in heap or literals?

    Question: I have a use case where I can get pointers of strings allocated either in memory or litera ...

随机推荐

  1. SpringBoot扩展点全攻略:让你的代码像积木一样灵活组装

    SpringBoot扩展点全攻略:让你的代码像积木一样灵活组装 小李正在开发一个电商系统,老板突然说:"我们要在用户登录时发送短信通知,在订单支付后要积分奖励,在系统启动时要预热缓存...& ...

  2. HarmonyOS免密认证方案 助力应用登录安全升级

    6月21日,2025年华为开发者大会"安全与隐私分论坛"在松山湖顺利举办.本论坛聚焦App治理与监管.星盾安全2.0的核心能力等进行深度分享与探讨.其中,HarmonyOS Pas ...

  3. MySQL 07 行锁功过:怎么减少行锁对性能的影响?

    行锁是针对数据表中行记录的锁,是在引擎层由引擎实现的. 从两阶段锁说起 在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立即释放,而是等到事务结束时才释放,这就是两阶段锁协议. 知 ...

  4. Xamarin.Android 特性-ActivityAttribute -中文说明

    using System; // 指定该特性用于类,并且不可重复或被继承 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, ...

  5. android打电话简单功能(完整代码)

    MainActivity.java: 1 package broadcastreceiver.lgqrlchinese.com.heima76android_1_phonedall; 2 3 impo ...

  6. 支撑 1300 万月活的幕后真相:Figma 是怎么把核心服务搬上 EKS 的?

    本文由 CloudPilot AI 编译,转载请联系marketing@cloudpilot.ai 近日,设计软件新贵 Figma 正式递交 IPO 申请,有望成为 2025 年规模最大的科技上市案. ...

  7. C++线程池 基于C的实现 学习1

    简介 线程池是什么? 打饭的阿姨们 前去吃饭的人们,任务 管理组件 线程池由三部分组成 执行队列,线程s 任务队列,任务s 管理组件 类似于 银行营业厅 食堂打饭 每个打饭的人都是一个线程 管理制度 ...

  8. ovm 格式的 六面体网格 样例 正方体的生成程序和文件

    简介 Hexahedron 六面体网格,基于 openVolumeMesh 格式的程序生成cube code // C++ includes #include <iostream> #in ...

  9. cgal 的初步学习

    简介 cgal 其实说白了就是一个封装好的图形学计算库.因为有很多函数我们经常用到为什么不把他们封装好呢? https://www.cgal.org/ 官网 https://blog.csdn.net ...

  10. Management-DecisionMaking-Leadership-Relationship: 组织关系管理: Authorization授权 与 “越级”操控 “人事布局、财物配置、审批授权赋能”

    Management-DecisionMaking-Leadership-Relationship: 组织关系管理: 组织关系 的 Authorization"授权" 与 &quo ...