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

1389A. LCM Problem

害,水题a的太慢,一开始还想着暴力,时间复杂度都没看,还有没用longlong结果交了3次,后面的不会,水题a的慢,得改改。

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


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
long gcd(long a,long b)
{
    return b?gcd(b,a%b):a;
}
long lcm(long a,long b)
{
    return a*b/(gcd(a,b));
}
int main()
{
    long long  t,l,r;
    cin>>t;
    while(t--)
    {
        scanf("%lld %lld",&l,&r);
        if(r/l>1)
            {printf("%lld %lld\n",l,l*(r/l));continue;}
        else printf("-1 -1\n");
    }
    return 0;
}

1389B. Array Walk

这题我题目都没读懂,还不知道不能连续往左移动,并且一度认为会有可能在多个地方左右移动。。我tcl

题意:给你一个数组,有n个数。初始位置在下标为1的a1处,你可以在数组上进行移动k次。移动到某个位置时,你可以得到相对应的分数。但有两个限制。不能连续两次向左移动,并且向左移动的次数不能超过z次。问最后最高可以得到多少分。

思路:可以枚举 2—n 的位置上,左右移动1-z次。选择得分最高的情况。 具体实现看代码中的注释。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int main()
{
    int t,n,k,z,a[N],sum[N];
    cin>>t;
    while(t--)
    {
        memset(sum,0,sizeof(sum));
        scanf("%d %d %d",&n,&k,&z);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        //初始最大是只往右走
        int ans=sum[k+1];
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<=z;j++)
            {
                //这里要按k的奇偶性讨论,区别在与能否回到a[i]
                if(2*j+i-1<=k)
                ans=max(ans,sum[k-j*2+1]+j*(a[i]+a[i-1]));
                if(2*j+i-2<=k)
                    ans=max(ans,sum[k-j*2+1]+j*(a[i]+a[i-1]));
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

1389C. Good String

题意:定义一种Good String为字符串t=t1t2t3…tn−1tn,它满足t2t3…tn−1tnt1= tnt1t2t3…tn−1
现给出一个仅有0-9组成的字符串s判断它最少要删除多少个字符才能变成Good String

首先快速理解题意,将英文转化为中文存到脑子里,再根据题意将公式转化,推导出更易理解的式子。
这个题就是先推导出a[x]=a[x+2],然后根据这个来采取策略,可以先演算找的过程,再将这个过程转化为代码。
方法就是:枚举00-99,这100种情况,每种情况与第一个字母相等就检验第二个个字母,不对的话就往后推

#include <bits/stdc++.h>
using namespace std;
const int N=2e5;
typedef long long ll;
string a;
int main()
{
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>a;
        int len=a.length();
        int now,tmp,ans=99999999;
        for(int i=0;i<10;i++)
        {
            for(int j=0;j<10;j++)
            {
                now=0,tmp=0;
                while(now<len)
                {
                    //不相等的话就指针后移,删除数+1
                    while(now<len&&a[now]!=i+'0')now++,tmp++;
                    now++;
                    //检验第二个字母
                    while(now<len&&a[now]!=j+'0')now++,tmp++;
                    now++;
                }
                if(i!=j&&((len-tmp)&1))tmp++;
                ans=min(ans,tmp);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值