Codeforces Round 925 (Div. 3)

这篇文章介绍了CodeforcesRound925比赛中的五个问题,涉及字符串恢复、整数序列调整、数学运算和数据结构应用。A题使用暴力搜索,B、C题通过模拟解决,D题运用数论,E题结合Multiset进行分析,展示了算法和数据结构在竞赛中的运用。
摘要由CSDN通过智能技术生成

Codeforces Round 925(Div. 3)

A. Recovering a Small String

暴搜

一共就三个字母,我们只要每次从第一个字母开始,如果搜满三个字母,且正好总和为n,那么这就是答案,直接返回即可。

时间复杂度: 2 6 3 26^3 263

#include<bits/stdc++.h>
using namespace std;

bool is_yes=0;
void dfs(int n,int pos,string s){
    if(is_yes==1)return;
    if(pos==4 and n!=0)return;
    if(pos==4 and n==0){
        cout<<s<<endl;
        is_yes=1;
        return;
    }
    for(int i=0;i<26;i++){
        if(i<=n){
            char c=i+'a';
            dfs(n-i-1,pos+1,s+c);
        }
    }
}
void slove(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        string s;
        is_yes=0;
        dfs(n,1,s);
    }
}

int main(){
    slove();
}

B. Make Equal

模拟

算出平均数,然后从1开始,将多了的传递给下一个,直到最后一个,再检查一下第一个和最后一个是否为平均数即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long

void slove(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector<ll> a(n+1);
        for(int i=1;i<=n;i++)cin>>a[i];
        ll sum=0;
        for(int i=1;i<=n;i++){
            sum+=a[i];
        }
        ll ans=sum/n;
        for(int i=1;i<=n-1;i++){
            if(a[i]>ans){
                ll cha=a[i]-ans;
                a[i+1]+=cha;
                a[i]-=cha;
            }
        }
        bool is_yes=1;
        for(int i=1;i<=n;i++){
            if(a[i]!=ans){
                is_yes=0;
                break;
            }
        }
        if(is_yes==1)cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}

int main(){
    slove();
}

C. Make Equal Again

模拟

由于只有一次操作,所以我们只能从两端开始收缩

先记录从1开始,连续相等的个数t1

再记录从n开始,连续相等的个数t2

如果a[1]==a[n],那么答案就是n-t1-t2

如果不等,那么取最小的 min(n-t1,n-t2)

#include<bits/stdc++.h>
using namespace std;
#define ll long long

void slove(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector<int> a(n+1);
        for(int i=1;i<=n;i++)cin>>a[i];
        
        int t1=a[1];
        int pos1=1;
        for(int i=2;i<=n;i++){
            if(a[i]==t1)pos1++;
            else break;
        }
        int t2=a[n];
        int pos2=1;
        for(int i=n-1;i>=1;i--){
            if(a[i]==t2)pos2++;
            else break;
        }
        if(t1==t2){
            int ans= max(0,n-pos2-pos1);
            cout<<ans<<endl;
        }
        else{
            int ans= min(n-pos1,n-pos2);
            cout<<ans<<endl;
        }
        
        
    }
}

int main(){
    slove();
}

D. Divisible Pairs

数论同余

a i = p 1 x + r 1   , a j = p 2 x + r 2 a_i=p_1x+r_1\ ,a_j=p_2x+r_2 ai=p1x+r1 ,aj=p2x+r2

a i + a j = p 1 x + r 1   + p 2 x + r 2 a_i+a_j=p_1x+r_1\ +p_2x+r_2 ai+aj=p1x+r1 +p2x+r2

所以只需要满足 r 1 + r 2 ≡ 0 ( m o d   x ) r_1+r_2\equiv0(mod\ x) r1+r20(mod x)

同理

a i = p 1 y + r 1   , a j = p 2 y + r 2 a_i=p_1y+r_1\ ,a_j=p_2y+r_2 ai=p1y+r1 ,aj=p2y+r2

a i − a j = p 1 x + r 1   − p 2 x − r 2 a_i-a_j=p_1x+r_1\ -p_2x-r_2 aiaj=p1x+r1 p2xr2

只需要 r 1 − r 2 ≡ 0 ( m o d   y ) r_1-r_2\equiv0(mod\ y) r1r20(mod y)

对于x,我们需要特判一下r1=r2=0的情况

一般情况就是 r2=x-r1

对于y,我们只要找 r1=r2的个数就行

开map记录数对,并且倒序输入(因为题目要求i<j)

ps:赛场上没写出来的原因是卡在特判了,我只找了 x-r1的情况

再加上手速比较慢,所以d花了很多时间,导致e差几分钟就能写完。

#include<bits/stdc++.h>
using namespace std;
#define ll long long


void slove(){
    int t;
    cin>>t;
    while(t--){
        ll n,x,y;
        cin>>n>>x>>y;
        vector<ll> a(n+1);
        for(int i=1;i<=n;i++)cin>>a[i];
        
       //x意义,y意义,id,个数
        map<pair<ll,ll>,int >m;
        ll ans=0;
        for(int i=n;i>=1;i--){
            ll xyu,yyu;
            xyu=a[i]%x;
            yyu=a[i]%y;
            
           ll t=x-xyu;
            if(xyu==0)t=0;
            
            if(m.count({t,yyu}) ){
                ans+=m[{t,yyu}];
            }
            m[{xyu,yyu}]++;
        }
        cout<<ans<<endl;
    }
}

int main(){
    slove();
}

E. Anna and the Valentine’s Day Gift

Multiset / 数据结构 / 模拟 /思维

先手Anna,她最优的操作是反转后置0最多的数,使得总位数减少的多。

后手Sasha,需要将后置0最多的数和后置零最少的数合并。

后置零最少的数一定是0,因为Anna每一次操作都会将后置0清空。

所以记录位数之和,然后记录每个数的后置0,并按后置0个数从大到小排序

然后减去奇数次的即可。

嗯。。没错,这是我刚刚写题解的时候想到的,我估计正解就是这样。

我最开始的想法是模拟,将所有数据插入multiset中,然后当sasha操作的时候,取出里面最大的和最小的,合并,然后放回multiset中。

我发现我好蠢啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看一下两者的内存差距。

下面给出优化版的E题代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long

bool cmp(int a,int b){
    return a>b;
}



void slove(){
    int t;
    cin>>t;
    while(t--){
        
        int n,m;
        cin>>n>>m;
        vector<int> big(n+1);
        vector<int> a(n);
        ll sum=0;
        
        for(int i=0;i<n;i++){
            ll t;
            cin>>t;
            int cnt=0; //记录后置0
            int bnt=0; //记录位数
            ll temp=t;
            while(temp){
                if(temp%10==0)cnt++;
                else break;
                temp/=10;
            }
            while(t){
                bnt++;
                t/=10;
            }
            sum+=bnt; //记录总位数
            a[i]=cnt; //记录每一个数的后置0个数
            
        }
        sort(a.begin(),a.end(),cmp);
        for(int i=0;i<n;i++){
            if((i+1)&1)sum-=a[i];
        }
        if(sum-1>=m)cout<<"Sasha"<<endl;
        else cout<<"Anna"<<endl;
    }
}

int main(){
    slove();
}

}
sum+=bnt; //记录总位数
a[i]=cnt; //记录每一个数的后置0个数

    }
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<n;i++){
        if((i+1)&1)sum-=a[i];
    }
    if(sum-1>=m)cout<<"Sasha"<<endl;
    else cout<<"Anna"<<endl;
}

}

int main(){
slove();
}




  • 52
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值