Codeforces Round #617 (Div. 3)(A~D)

打比赛前先刷个虚拟赛热热身…
传送门
在这里插入图片描述
水题
题目意思是给出一个数组 可以使任意一个位置的数大小变成它后面的数
不限次数,请问是否可以使得最后数组元素之和是一个奇数
很简单 数组之和不是偶数就是奇数 奇数直接输出,偶数的话 只需要改变任意一个数的奇偶值就好即奇数->偶数 or 偶数->奇数 就可以使总和为奇数了
所以我们在输入的时候类和整个数组 ,再记录下相邻元素之间的差值是否有一个是奇数(因为一个数加上奇数才能改变奇偶)
和为奇数符合条件,和为偶数但差值存在奇数也符合条件

void solve()
{
    int n=read();
    int sum=0,f=0;
    rep(i,1,n)
    {
        arr[i]=read();
        sum+=arr[i];
        if(i!=1&&abs(arr[i]-arr[i-1])%2==1)
            f=1;
    }
    if(sum%2==1||f)
        puts("YES");
    else
        puts("NO");
}

在这里插入图片描述
纯粹数学题…你可以理解为你起初有n瓶饮料,然后10个瓶盖可以兑换一瓶饮料,给出最初饮料数目,求出一共可以喝多少饮料…就是一个数学题…

void solve()
{
    ll n=read();
    ll sum=0;
    while(n>=10)
    {
        sum=sum+n/10*10;
        n=n/10+n%10;
    }
    printf("%lld\n",sum+n);
}

在这里插入图片描述
先吹一波pair真的好用!!
题目意思是给出一个操作序列,lrud对应左右上下,让你删减最短的连续片段,使得终点不变,可以的话输出最短片段的两个边界,反之输出-1
首先我的想法是开一个结构体lrud记录下每个位置前面l,r,u,d分别有多少,然后看一看是否有两个位置的l1-l2r1-r2且u1-u2d1-d2很麻烦。。。
然后越写越乱,而且复杂度感人…
之后参照了大佬的写法…我真是蒟蒻 我记录lr,u,d的相对关系就是看看有没有能删除的,也就是说有两个下标对应的点是不是在同一点!
我的思路是找lrud数量关系,大佬直接开个pair加map储存x,y来记录是否有地方重复到达过…即

 if(mp[{x,y}]!=0&&mn>(i-mp[{x,y}]+1))
 {
      mn=i-mp[{x,y}]+1;
      l=mp[{x,y}];
      r=i;
 }

直接判断这个点是否到达过,且符合条件时比较距离…

void solve()
{
    int n=read();
    int mn=n+1,l=0,r=n+1,x=0,y=0;
    map<pii,int>mp;
    mp[{0,0}]=1;
    rep(i,1,n)
    {
        char ch=getchar();
        if(ch=='L')
            x--;
        if(ch=='R')
            x++;
        if(ch=='U')
            y++;
        if(ch=='D')
            y--;
        if(mp[{x,y}]!=0&&mn>(i-mp[{x,y}]+1))
        {
            mn=i-mp[{x,y}]+1;
            l=mp[{x,y}];
            r=i;
        }
        mp[{x,y}]=i+1;
    }
    if(mn==n+1)
        puts("-1");
    else
        printf("%d %d\n",l,r);
}

害…巨大的差距…
推荐写成 make_pair吧 尽量少用{}
在这里插入图片描述
题目意思简单
n个野怪,打野攻击力为a,辅助攻击力为b,两个人交替平a野怪,谁打死的野怪金币给谁(即最后一刀砍死的人)但是打野能开k次挂,每次开挂可以在辅助砍之前再砍一次,可以在同一时间多次开挂,每只野怪金币都是1,给出每只野怪的血量,请问打野最多可以获得多少金币
很明显贪心sort一下就好了,我们知道每只野怪死在谁手里不是看血量多少,而是看血量和两人攻击之和之间的关系
假设血量为num
num%(a+b)==0时 辅助砍死
num%(a+b)不等于0时,剩余血量小于等于a ,打野砍死
反之辅助砍死(打野可以开挂若干次强行砍死)
每只野怪金币一样,所以我们应该尽量把开挂次数用在需要开挂次数少的野怪身上,显然本身属于打野的耗费次数是0,反之就是
int res=num%(a+b)

res==0时res=b(退一回合)
所需开挂次数为 ceil(res/a) 剩余血量除于打野攻击力向上取整
所以sort条件为 res为0时 放后面,反之把res小的放前面

bool cmp(int x,int y)
{
    int r1=x%(a+b),r2=y%(a+b);
    if(r1==0||r2==0)
    {
        return r1>r2;
    }
    else
    {
        return r1<r2;
    }
}

总代码是

bool cmp(int x,int y)
{
    int r1=x%(a+b),r2=y%(a+b);
    if(r1==0||r2==0)
    {
        return r1>r2;
    }
    else
    {
        return r1<r2;
    }
}
int main()
{
    n=read(),a=read(),b=read(),k=read();
    rep(i,1,n)
    {
        arr[i]=read();
    }
    sort(arr+1,arr+n+1,cmp);
    int ans=0;
    rep(i,1,n)
    {
        if(k<=0)
            break;
        int res=arr[i]%(a+b);
        if(res==0)
        {
            int cnt=ceil(b*1.0/a);
            if(cnt<=k)
                ans++;
            k-=cnt;
        }
        else
        {
            if(res<=a)
                ans++;
            else
            {
                res-=a;
                int cnt=ceil(res*1.0/a);
                if(cnt<=k)
                    ans++;
                k-=cnt;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leoxe/article/details/105127866