Educational Codeforces Round 92 (Rated for Div. 2)题解(A-C)

A.LCM Problem

题意:给定两个整数定义的闭区间 [ l , r ] [l,r] [l,r],让你在区间内找出两个数 x , y x,y x,y满足 L C M ( x , y ) ≤ r LCM(x,y) \le r LCM(x,y)r
思路:容易验证 L C M ( x , y ) LCM(x,y) LCM(x,y)至少是 m i n ( x , y ) min(x,y) min(x,y)的二倍,所以直接构造一组最小的解 ( l , 2 l ) (l,2l) (l,2l)

#include <bits/stdc++.h>
using namespace std;
 
int main() {
    int t;
    cin>>t;
    while(t--){
        long long l,r;
        cin>>l>>r;
        if(l*2<=r) cout<<l<<' '<<2*l<<endl;
        else cout<<"-1 -1"<<endl;
    }
    return 0;
}

B.Array Walk

题意:给定一个序列 { a 1 , a 2 , a 3 , . . . , a n } \{a_1,a_2,a_3,...,a_n\} {a1,a2,a3,...,an},你一开始站在1的位置并且拥有权值 a 1 a_1 a1,你可以向右或向左走,每走到一个位置,权值和就加上此位置的权值,限制是可以不能连续向左走。例如移动序列可以是 { 1 , 2 , 1 , 2 , 1 , 2 } \{1,2,1,2,1,2 \} {1,2,1,2,1,2}但是不能是 { 1 , 2 , 3 , 2 , 1 } \{1,2,3,2,1\} {1,2,3,2,1},问走 k k k步,最多向左走 z ( z ≤ 5 ) z(z\le5) z(z5)步,最后权值和最大是多少。
思路:首先计算全部向右走的和 s u m [ k + 1 ] sum[k+1] sum[k+1],并处理过程中相邻两格的和(考虑向左一步又向右一步的走法),当最大的相邻和所在两格不是最后两格的时候,我们选择将最后的向右两步走变为在最大相邻和的地方左右走,序列结束的位置 e d ed ed也就相应往左移两位,由于 z z z比较小,可以枚举向左走 ( 1 − z ) (1-z) (1z)步的情况取最大值。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
ll sum[maxn],a[maxn],s2[maxn];
int main() {
    int t;
    cin>>t;
    ll n,k,z;
    while(t--){
        cin>>n>>k>>z;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=1;i<n;i++) s2[i]=a[i]+a[i+1];
        ll ans=sum[k+1],ed=k+1,m=-1;
        for(int p=1;p<=z;p++){
            ed=k+1-p*2;
            m=-1;
            if(ed<1) break;
            for (int i = 1; i <= ed; i++) m=max(m,s2[i]);
            ans = max(sum[ed]+ m*p,ans);
        }
        cout<<ans<<endl;
    }
    return 0;
}

C. Good String

题意:给定一个由 0 ∼ 9 0\sim9 09 构成的字符串 s = t 1 t 2 ⋯ t n s=t_1t_2⋯t_n s=t1t2tn,询问最少从 s s s中删除几个字符,使得新得到的字符串满足: t 2 t 3 ⋯ t n − 1 t n t 1 = t n t 1 t 2 ⋯ t n − 2 t n − 1 t_2t_3⋯t_{n−1}t_nt_1=t_nt_1t_2⋯t_{n−2}t_{n−1} t2t3tn1tnt1=tnt1t2tn2tn1
思路:容易得到: t 1 = t 3 = t 5 = ⋅ ⋅ ⋅ ∩ t 2 = t 4 = ⋅ ⋅ ⋅ t n t_1=t_3=t_5=··· \cap t_2=t_4=···t_n t1=t3=t5=t2=t4=tn因此,该字符串的构成最多只有两种字符,并且有两种字符时,必定形如 121212 ⋯ 121212⋯ 121212的形式。由于该字符串由 0 ∼ 9 0\sim 9 09 构成,一共只有 10 × 10 + 10 10\times 10+10 10×10+10 种情况(相邻的两位数的情况、全部数字相同),直接暴力枚举即可。
记录错误:这里要注意的是形如 2323213232323 2323213232323 2323213232323这种两两重复但是中间插了一个数字的情况,一开始我并没有考虑到,只进行了相邻的数字数量计数,错误代码会输出3,正确的做法应该是枚举 1 ∼ 99 1\sim99 199的所有数字,计算如果只保留这两种数字的交替出现,应该删除多少字符;然后算一下只保留一种字符需要删除的字符数量,二者取一个 m i n min min即可。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
ll sum[111],cnt[11];
int main() {
    int t;
    cin>>t;
    ll n,k,z;
    while(t--){
        memset(sum,0,sizeof(sum));
        memset(cnt,0,sizeof(cnt));
        string str;
        cin>>str;
        int len=str.size();
        if(len<=2){
            cout<<0<<endl;
            continue;
        }
        for(int i=0;i<len;i++) cnt[str[i]-'0']++;
        ll m=-1,mm=-1;
        for(int a=0;a<10;a++){
            for(int b=0;b<10;b++){
                m=0;
                for(int i=0;i<len;i++){
                    int x=str[i]-'0';
                    if(m&1){
                        if(x==a) m++;
                    }
                    else{
                        if(x==b) m++;
                    }
                }
                m-=(m&1);
                mm=max(mm,m);
            }
        }
        m=-1;
        for(int i=0;i<10;i++) m=max(m,cnt[i]);
        cout<<min(len-m,len-mm)<<endl;
    }
    return 0;
}

这场分掉的真难受,都是思路对了但是最后写炸了;接下来会补题

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值