CF2111E

首先可以把所有操作的类型及时间记录下来,分类存进 map 里。

根据贪心,显然越靠前的字母越小越好。从前往后考虑每位 \(s_i\)

  • \(s_i=a\) 已经最优了,无需处理。
  • \(s_i=b\) 优先考虑 \(b \rightarrow a\),如果不存在这样的操作就考虑 \(b \rightarrow c \rightarrow a\)(先找 \(b \rightarrow c\) 是否存在,存在则取时间最早的,并在 \(c\rightarrow a\) 中找到第一个时间在它后面的,若能找到则更新,并同时删除两个操作)。
  • \(s_i=c\) 优先考虑 \(c \rightarrow a\),如果不存在则考虑 \(c\rightarrow b\rightarrow a\)(先找 \(c \rightarrow b\) 是否存在,存在则取时间最早的,\(s_i\leftarrow b\),并在 \(b\rightarrow a\) 中找第一个时间在它后面的,此时再删除第一步的操作。若能找到则更新为 \(a\)并删除该操作)。

注意实现时一定要先查找完再删除对应的迭代器,否则会因迭代器无效而导致 RE。

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
map<int,int> ba,bc,ca,cb;
string s;
int n,m;
char x,y;
void solve(){
    ba.clear();bc.clear();ca.clear();cb.clear();
    cin>>n>>m;
    cin>>s;
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        if(x=='b'&&y=='a')ba[i]=i;
        if(x=='b'&&y=='c')bc[i]=i;
        if(x=='c'&&y=='b')cb[i]=i;
        if(x=='c'&&y=='a')ca[i]=i;
    }
    for(int i=0;i<n;i++){
        // cout<<i<<endl;
        if(s[i]=='a')continue;
        if(s[i]=='b'){
            if(ba.size()){
                auto it=ba.begin();
                ba.erase(it);
                s[i]='a';
            }
            else if(bc.size()){
                auto it=bc.begin();
                auto it1=ca.upper_bound(it->second);
                if(it1!=ca.end()){
                    s[i]='a';
                    bc.erase(it);
                    ca.erase(it1);
                }
            }
        }
        if(s[i]=='c'){
            if(ca.size()){
                auto it=ca.begin();
                ca.erase(it);
                s[i]='a';
            }
            else if(cb.size()){
                auto it=cb.begin();
                s[i]='b';
                auto it1=ba.upper_bound(it->second);
                cb.erase(it);//必须先查找再删迭代器,否则 it 指向的迭代器无效会发生 Runtime Error。或者记录迭代器对应的值也可以
                if(it1!=ba.end()){
                    s[i]='a';
                    ba.erase(it1);
                }
            }
        }
    }
    cout<<s<<'\n';
    return;
}
int main(){
    int T;
    cin>>T;
    while(T--)
        solve();
    return 0;
}
posted @ 2025-09-12 08:13  FormulaOne  阅读(4)  评论(0)    收藏  举报