Educational Codeforces Round 92 (Rated for Div. 2)

A

签到

B

直接DP,f[i][j]表示前i步j步向左的最大值,位置可以直接计算

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,k,z,ans,a[N],f[N][6];
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&k,&z);
        for(int i=1;i<=n;i++)for(int j=0;j<=z;j++)f[i][j]=0;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        f[0][0]=a[1];
        for(int i=1;i<=k;i++)
        for(int j=0;j<=min(i-1,z);j++)
        {
            int pos=i-2*j;
            if(pos>1&&j<z)f[i][j+1]=max(f[i][j+1],f[i-1][j]+a[pos-1]);
            if(pos<n)f[i][j]=max(f[i][j],f[i-1][j]+a[pos+1]);
        }
        ans=0;
        for(int i=0;i<=z;i++)ans=max(ans,f[k][i]);
        printf("%d\n",ans);
    }
}
View Code

C

求最少删除次数等价于求最长序列。容易发现,最长序列有两种情况:1、全为字符a;2、长度为偶数,ababab交替。方案1记录数量最多的数字,方案2枚举ab扫描一遍即可,复杂度O(81Σn)

#include<bits/stdc++.h>
using namespace std;
int n,ans;
char s[200050];
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s+1);
        n=strlen(s+1);
        int num;
        ans=0;
        for(int i='0';i<='9';i++)
        {
            num=0;
            for(int j=1;j<=n;j++)if(s[j]==i)num++;
            ans=max(ans,num);
        }
        for(int a='0';a<='9';a++)
        for(int b='0';b<='9';b++)
        if(a!=b)
        {
            int now=a,num=0;
            for(int i=1;i<=n;i++)if(s[i]==now)
            {
                num++;
                now=now==a?b:a;
            }
            if(num%2)num--;
            ans=max(ans,num);
        }
        printf("%d\n",n-ans);
    }
}
View Code

D

对于两条线段,不妨三种情况:1、完全包含;2、部分包含;3、无交集。前两种直接计算,尽量改变重叠部分。第三种可以枚举改变i组线段,然后转化为第二种方案。时间复杂度O(Tn)(不然T,n给你那么小干嘛?)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll n,k,l1,r1,l2,r2,ans;
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n>>k>>l1>>r1>>l2>>r2;
        if(l1>l2||l1==l2&&r1<r2)swap(l1,l2),swap(r1,r2);
        if(r1>=r2)
        {
            ll rst=(r1-l1)-(r2-l2);
            if(k<=(r2-l2)*n)puts("0");
            else if(k<=(r1-l1)*n)printf("%lld\n",k-(r2-l2)*n);
            else printf("%lld\n",rst*n+(k-(r1-l1)*n)*2);
        }
        else if(r1>=l2)
        {
            ll rst=(r2-l1)-(r1-l2);
            if(k<=(r1-l2)*n)puts("0");
            else if(k<=(r2-l1)*n)printf("%lld\n",k-(r1-l2)*n);
            else printf("%lld\n",rst*n+(k-(r2-l1)*n)*2);
        }
        else{
            ans=9e18;
            for(int i=1;i<=n;i++)
            {
                ll sum=i*(l2-r1);
                if(k<=(r2-l1)*i)sum+=k;
                else sum+=(r2-l1)*i+(k-(r2-l1)*i)*2;
                ans=min(ans,sum);
            }
            printf("%lld\n",ans);
        }
    }
}
View Code

E

老年选手不会用脑子了!若a月b日和b月a日如果是一周的同一天,则(b-1)*d+a-( (a-1)*d+b)被w整除,化简得(b-a)(d-1)%w==0,设c=b-a,则c*(d-1)%w==0。若(d-1)%w=0,则c为任意正整数 ,ans=md*(md-1)/2,md=min(m,d)。若(d-1)%w!=0,那c是lcm(w,(d-1)%w)/(d-1)%w的整数倍

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int m,d,w,g;scanf("%d%d%d",&m,&d,&w);
        g=__gcd(w,d-1),w/=g,m=min(m,d);
        long long y=m/w;
        printf("%lld\n",y*m-y*(y+1)/2*w);
    }
}
View Code

rank=216 rating+=222

新号卡线上紫啦!

猜你喜欢

转载自www.cnblogs.com/hfctf0210/p/13401960.html