Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round)(A-C题解)

Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) 

原题地址:https://codeforces.ml/contest/1321

A:Contest for Robots

题意:共有n场比赛,A,B两人参赛,0表示本场比赛不得分,1表示得分。给出AB两人的比赛情况,请你制定每场比赛的得分(最低为1分),使得A的最终分数比B多且尽可能使两人分数相差不大,如果可以,输出得分最高的那场比赛,如果无论怎样指定得分A都不会比B多输出-1;

思路:如果某场比赛AB都得分了,那么两人分数一定相同,关键在于两人多得到的分数,所有分别用a,b表示A赢得比赛但B没赢的场数和B赢的比赛但A没赢的场数。

如果a = 0 说明 a 没有额外赢得比赛,无论分数怎么指定,B的分数一定大于等于A的分数 输出-1

如果a > b 说明就算每场比赛都是1分,A的总分也比B高,输出1

但 a < b 时,为了使得输出尽可能小,就只能让B多赢的比赛为1分,只要a某场比赛得分比 b/a 大就行(注意不能整除的情况)

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
 
int main()
{
    int n;
    cin>>n;
    int a[110];
    int b[110];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    int x,xa,xb;
    x=xa=xb=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==1&&b[i]==1) x++;
        else if(a[i]==1) xa++;
        else if(b[i]==1) xb++;
    }
    if(xa==0) cout<<-1<<endl;
    else
    {
        if(xa>xb) cout<<1<<endl;
        else
        {
            double t = 1.0*xb/xa;
            if(xb%xa==0) t+=1;
            else{
                t = ceil(t);
            }
            cout<<t<<endl;
        }
 
    }
//    cout<<x<<" "<<xa<<" "<<xb<<endl;
    return 0;
}
View Code

B:Journey Planning

题意:给定一个下标为1到n 的数组b,请你在1到n中选一个递增数列c使得对应b数组的值的和最大,且满足①c[i+1] - c[i] = b[ c[i+1] ] - b[ c[i] ]

思路: 数据太大,双层循环会超时

仔细观察会发现  b中元素减下标 结果相同的 就满足 式子①,式子①可以转化为b[ c[i+1] ]-c[i+1] = b[ c[i] ] - c[i]

此时再分别把差相同的分为一组求和,最大的就是想要的结果

差值相同则相加可以用map计算,用差值作为key,对应b的和为value

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef pair<ll,ll> PAIR;
const int maxn = 2e5+5;
map<ll ,ll > s;
//bool cmp(const PAIR& a, const PAIR& b)
//{
//    return a.second>b.second;
//}
int main()
{

    int n;
    cin>>n;
    ll b[maxn];
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    ll ans = 0;
    for(int i=1;i<=n;i++)
    {
       s[b[i]-i]+=b[i];
       ans = max(ans,s[b[i]-i]);
    }
    cout<<ans<<endl;
    return 0;
}
View Code

C:Remove Adjacent

题意:给定一串字母,你可以删除某个元素i 规则是,i-1或者i+1的位置上的字母是i字母的上一个字母,删除后原来两段在合并成一段即i-1与i+1相邻了,请输出最多可以删除几个元素

思路: i周围有i上一个字母则可以删,如果从z开始删除则不会影响前面的字母,由于数据范围较小100,直接模拟就行,从字典序列大的开始删除 注意!正向遍历一遍后 在反向遍历一次。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef pair<ll,ll> PAIR;
const int maxn = 2e5+5;
int vis[30]={0};
int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    for(int i=0;i<s.length();i++)
    {
        vis[s[i]-'a']++;
    }
    int ans = 0;
    for(int j=25;j>=0;j--)
    {
        if(vis[j]==0) continue;
        for(int i=0;i<s.length();i++)
        {
            if(s[i]-'a'==j)
            {
                if((s[i-1]-'a'==j-1&&i-1>=0)||(s[i+1]-'a'==j-1&&i+1<=s.length()))
                {
                    s.erase(i,1);
                    i--;//删除后i+1变为了i,而此时表示的是i+1
                    ans++;
                }

            }
        }
        //反向
        for(int i=s.length()-1;i>=0;i--)
        {
            if(s[i]-'a'==j)
            {
                if((s[i-1]-'a'==j-1&&i-1>=0)||(s[i+1]-'a'==j-1&&i+1<=s.length()))
                {
                    s.erase(i,1);
                    i++;
                    ans++;
                }

            }
        }

    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

posted @ 2020-03-02 17:42  精神小伙儿  阅读(240)  评论(0编辑  收藏  举报