Educational Codeforces Round 102 (Rated for Div. 2) A~D题解

A. Replacing Elements

  • 解题思路
    我们需要用两个元素之和来代替另一个元素。使得数组中的所有元素小于等于 d d d。那么如果所有本来就小于等于 d d d,那么我们自然不用替代。否则按照贪心思想,以最小的两个元素去代替,那么二者之和必须小于等于 d d d。满足这两个条件即可。

  • AC代码

/**
  *@filename:A_Replacing_Elements
  *@author: pursuit
  *@csdn:unique_pursuit
  *@email: 2825841950@qq.com
  *@created: 2021-07-02 11:30
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 100 + 5;
const int P = 1e9+7;

int t,n,d,a[N];
void solve(){
    sort(a + 1, a + 1 + n);
    if(a[1] + a[2] <= d || a[n] <= d){
        cout << "YES" << endl;
    }
    else{
        cout << "NO" << endl;
    }
}
int main(){
    cin >> t;
    while(t -- ){
        cin >> n >> d;
        for(int i = 1; i <= n; ++ i){
            cin >> a[i];
        }
        solve();
    }
    return 0;
}

B. String LCM

  • 解题思路
    对于字符串 a , b a,b a,b的最小公倍数,实际上就是通过重复 a , b a,b a,b得到的,所以我们可以不断重复,使得生成的字符串长度相等,再判断他们是否相等即可。

  • AC代码

/**
  *@filename:B_String_LCM
  *@author: pursuit
  *@csdn:unique_pursuit
  *@email: 2825841950@qq.com
  *@created: 2021-07-02 11:34
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 100000 + 5;
const int P = 1e9+7;

int t;
string s1,s2;
void solve(){
    string temp1 = s1,temp2 = s2;
    while(s1.size() != s2.size()){
        if(s1.size() < s2.size()){
            s1 += temp1;
        }
        else{
            s2 += temp2;
        }
    }
    if(s1 != s2){
        cout << -1 << endl;
    }
    else{
        cout << s1 << endl;
    }
}
int main(){
    cin >> t;
    while(t -- ){
        cin >> s1 >> s2;
        solve();
    }
    return 0;
}

C. No More Inversions

  • 题意

a a a序列 1 , 2 , 3 , 4 , . . k , k − 1 , k − 2 , . . . , k − ( n − k ) 1 , 2 , 3 , 4 , . . k , k − 1 , k − 2 , . . . , k − ( n − k ) 1,2,3,4,..k,k1,k2,...,k(nk)
求一个排列 p p p,使得 b [ i ] = p [ a [ i ] ] b[i]=p[a[i]] b[i]=p[a[i]],则b序列的逆序数不大于a序列,且b的字典序最大。

  • 解题思路
    我们知道,按照 a a a序列的排列,形成的 b b b序列则是将 p p p序列中和第 k − ( n − k ) k - (n - k) k(nk)和第 k − 1 k - 1 k1个数反转到后面去了,这样,第 k − ( n − k ) k - (n - k) k(nk)和第 n n n个数之间构成了回文串。而相同长度的回文串是固定的,那么真正影响逆序数的就是前面 k − ( n − k ) − 1 k − ( n − k )-1 k(nk)1 个数,为了不增加逆序对个数,我们只能按顺序排列。故此题得解。

  • AC代码

/**
  *@filename:C_No_More_Inversions
  *@author: pursuit
  *@csdn:unique_pursuit
  *@email: 2825841950@qq.com
  *@created: 2021-07-02 11:43
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 100000 + 5;
const int P = 1e9+7;

int t,n,k;
void solve(){
    if(n > k & k > 1){
        for(int i = 1; i <= k - (n - k + 1); ++ i){
            cout << i << " ";//回文串是固定的,只能填k - (n - k - 1)个数。
        }
        for(int i = k; i >= k - (n - k); -- i){
            cout << i << " ";
        }
    }
    else{
        for(int i = 1; i <= k; ++ i){
            cout << i << " ";
        }
    }
    cout << endl;
}
int main(){
    cin >> t;
    while(t -- ){
        cin >> n >> k;
        solve();
    }
    return 0;
}

D. Program

  • 解题思路
    由于我们进行的都是加 1 1 1 1 1 1操作,所以产生的数一定是连续的,所以我们可以找到剔除掉 [ l , r ] [l,r] [l,r]的上界和下界,这样就可以得到变化的 x x x数量了。那么如何找这上界和下界呢?直接遍历吗,这必然会超时。我们换种角度,剔除了 [ l , r ] [l,r] [l,r],无疑就得到了一个前缀 [ 1 , l − 1 ] [1,l-1] [1,l1]和一个后缀 [ r + 1 , n ] [r + 1,n] [r+1,n],那么如果我们找到了前缀的最小值和最大值,后缀的最小值和最大值。那么相加自然可以得到最小值和最大值了。前缀这里不作说明,对于后缀,我们需要从后往前,且注意更新的状态,因为后面是可以不必选的,所以起始值是 0 0 0,需要与 0 0 0作比较。具体看AC代码。

  • AC代码

/**
  *@filename:D_Program
  *@author: pursuit
  *@csdn:unique_pursuit
  *@email: 2825841950@qq.com
  *@created: 2021-07-02 14:44
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 200000 + 5;
const int P = 1e9+7;

int t,n,m,l,r;
int pre[N],pre_min[N],pre_max[N];
int suf[N],suf_min[N],suf_max[N];
char s[N];//操作指令。
int now;
void solve(){
    int now = 1;
    for(int i = 1; i <= n; ++ i){
        now = 1;
        if(s[i] == '-'){
            now = -1;
        }
        pre[i] = pre[i - 1] + now;
        pre_min[i] = min(pre_min[i - 1],pre[i]);
        pre_max[i] = max(pre_max[i - 1],pre[i]);
    }
    suf[n + 1] = suf_min[n + 1] = suf_max[n + 1] = 0;
    for(int i = n; i >= 1; -- i){
        now = 1;
        if(s[i] == '-'){
            now = -1;
        }
        suf[i] = suf[i + 1] + now;
        suf_min[i] = min(0,suf_min[i + 1] + now);
        suf_max[i] = max(0,suf_max[i + 1] + now);
    }
    while(m -- ){
        cin >> l >> r;
        int maxx = pre_max[l - 1],minn = pre_min[l - 1];
        maxx = max(maxx,suf_max[r + 1] + pre[l - 1]);
        minn = min(minn,suf_min[r + 1] + pre[l - 1]);
        cout << maxx - minn + 1 << endl;
    } 
}
int main(){
    cin >> t;
    while(t -- ){
        cin >> n >> m;
        cin >> s + 1;
        solve();
    }
    return 0;
}
posted @   unique_pursuit  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示