20230304 CF855 div3 vp

本文介绍了CodeforcesRound855(Div.3)中的几道编程题目,包括字符串模拟问题、计数配对问题、贪心策略应用等,展示了在解决这些问题时的思路和代码实现,强调了对字符串处理和算法运用的重要性。
摘要由CSDN通过智能技术生成

Dashboard - Codeforces Round 855 (Div. 3) - Codeforces

呃呃,评价是,毫无进步

呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃

该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了!!!

A Is It a Cat?

模拟

Problem - A - Codeforces

题意:

思路:

字符串模拟

SB模拟,__都不写

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#define int long long
using namespace std;
using i64 = long long;
const int mxn=1e6+10;
const int mxe=1e6+10;
const int mod=1e9+7;

string s;
int n;
int v_m,v_e,v_o,v_w;
void solve(){
    s.clear();
    v_m=0,v_e=0,v_o=0,v_w=0;
    cin>>n>>s;
    s=" "+s;
    for(int i=1;i<=n;i++){
        if(s[i]=='m'||s[i]=='M'){
            v_m=1;
            if(v_e||v_o||v_w){
                cout<<"NO"<<'\n';
                return;
            }
        }else if(s[i]=='e'||s[i]=='E'){
            v_e=1;
            if(v_o||v_w){
                cout<<"NO"<<'\n';
                return;
            }
        }else if(s[i]=='o'||s[i]=='O'){
            v_o=1;
            if(v_w){
                cout<<"NO"<<'\n';
                return;
            }
        }else if(s[i]=='w'||s[i]=='W'){
            v_w=1;
        }else{
            cout<<"NO"<<'\n';
            return;
        }
    }
    if(v_m&&v_e&&v_o&&v_w) cout<<"YES"<<'\n';
    else cout<<"NO"<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

B. Count the Number of Pairs

模拟

Problem - B - Codeforces

题意:

给你一个只有英文字母的字符串s,如果两个满足字符满足大小写关系,那么就说明他们是配对的。每对成功配对后的字符不可重复配对。给你一个k,你可以对任意字符进行大小写交换操作(最多k次),问你这个字符串最多有多少个配对。

思路:

又是SB字符串模拟

如果能配对就配对,不能就把不能的用map计数,然后考虑让同种字符配对,即把同性变成异性然后配对(

呃呃,像极了爱情

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#define int long long
using namespace std;
using i64 = long long;
const int mxn=1e6+10;
const int mxe=1e6+10;
const int mod=1e9+7;

vector<char> v;
map<char,int> mp;
int n,k;
string s;
void solve(){
    mp.clear();
    v.clear();s.clear();
    cin>>n>>k>>s;
    s=" "+s;
    int ans=0;
    for(int i=1;i<=n;i++){
        mp[s[i]]++;
        if(islower(s[i])){
            if(mp[s[i]-'a'+'A']!=0){
                ans++;
                mp[s[i]-'a'+'A']--;
                mp[s[i]]--;
            }
        }else{
            if(mp[s[i]-'A'+'a']!=0){
                ans++;
                mp[s[i]-'A'+'a']--;
                mp[s[i]]--;
            }
        }
    }
    //cout<<ans<<'\n';
    for(auto it:mp){
        //cout<<it.first<<" "<<it.second<<'\n';
        while(it.second>=2&&k>0){
            ans++;
            it.second-=2;
            k--;
        }
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

C1/C2. Powering the Hero

贪心

Problem - C1 - Codeforces

题意:

按顺序给你n张卡牌,这些卡牌分为两类:力量牌和角色牌。对于力量牌,你可以把它放在你的力量牌顶:对于角色牌(初始力量为0),你可以消耗最上方的力量牌排融入其中。问你他的所有角色的力量和的最大值是多少?

思路:

贪心,有角色牌一定是先选左边大的的力量牌,因此考虑用优先队列维护

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#define int long long
using namespace std;
using i64 = long long;
const int mxn=1e6+10;
const int mxe=1e6+10;
const int mod=1e9+7;

priority_queue<int> q;
int n;
int a[mxn];
void solve(){
    while(!q.empty()) q.pop();
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;i++){
        if(a[i]>0){
            q.push(a[i]);
        }else{
            if(!q.empty()) ans+=q.top(),q.pop();
        }
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

D.Remove Two Letters

特殊性质

Problem - D - Codeforces

题意:

给你一个长度为n的小写字符串,问你任意去除两个相邻的字符串之后,不同的字符串的种类有多少

思路:

一开始想维护前后缀然后去还原去掉那两个字符之后的新字符串,把新字符串放set里维护种类数

但是很不幸MLE了

因此一定是去考虑它的特殊性质,然后去优化

由于它只有两个相邻字符,当s[i]==s[i+2]时,去掉和没去掉是一样的,因此答案就是所有的减去这种去掉了和没去掉一样的情况

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define int long long
using namespace std;
using i64 = long long;
const int mxn=2e5+10;
const int mxe=1e6+10;
const int mod=1e9+7;

int n;
string s;
void solve(){
    s.clear();
    cin>>n>>s;
    s=" "+s;
    int ans=n-1;
    for(int i=1;i<=n;i++){
        if(s[i]==s[i+2]&&i+2<=n) ans--;
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

E1/E2. Unforgivable Curse

sorting

题意:

给你两个长度为n的只有英文的字符串a,b,然后给你一个k,你可以使si和s(i+k)或者si和s(i+k+1)交换,问你能否通过任意次交换,使得a,b字符串相等。

思路:

结论题

如果两个字符串每个字符出现次数不同,那么肯定不行

如果两个相邻位置能和同一个位置换位置,那么这两个相邻位置就可以凭借那个位置实现相邻位置之间元素互换

还有一个结论就是,如果两个相邻元素能互换位置,那么它可以和所有能换位置的位置的元素互换

这两个是sorting的一些结论

那么,我们可以搞出所有能换元素的位置,如果不能换元素的位置s[i]!=t[i],那么就一定不行

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define int long long
using namespace std;
using i64 = long long;
const int mxn=2e5+10;
const int mxe=1e6+10;
const int mod=1e9+7;

map<char,int> mp,mp2;
int n,k;
string s,t;
void solve(){
    mp.clear(),mp2.clear();
    s.clear(),t.clear();
    cin>>n>>k>>s>>t;
    s=" "+s;
    t=" "+t;
    for(int i=1;i<=n;i++){
        mp[s[i]]++;
        mp2[t[i]]++;
    }
    for(auto it:mp){
        if(mp2[it.first]!=it.second){
            cout<<"NO"<<'\n';
            return;
        }
    }
    for(int i=1;i<=n;i++){
        if(s[i]!=t[i]&&max(i-1,n-i)<k){
            cout<<"NO"<<'\n';
            return;
        }
    }
    cout<<"YES"<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

F. Dasha and Nightmares

(66条消息) 【异或哈希】CF855 div3 F_lamentropetion的博客-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值