Codeforces Round #616 (Div. 2)

Posted baihualiaoluan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #616 (Div. 2)相关的知识,希望对你有一定的参考价值。

QAQ我又开始更新了

A. Even But Not Even

题意:

给你一个数,你可以删去这个数中的某几位,使得到的新数是个奇数,但这个数的每位数之和是个偶数。如果可以输出新数,不可以输出-1

思路:

我们可以把所有的奇数都挑出来,这样的得到的数一定是个奇数,然后判断下长度,-1的情况就是长度为1时,此时不满足和是偶数且无法通过缩减长度达到满足条件。剩下的如果长度为偶数就直接输出,长度为奇数就不输出最后一位。

代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int len;
        string s;
        cin >> len;
        cin >> s;
        string t = "";
        for(int i= 0;i<len;++i)
        {
            if((s[i]-0)%2==1)
            {
                t+=s[i];
            }
        }
        int k = t.size();
        if(k<=1)
        {
            printf("-1
");
        }
        else
        {
            if(k%2==0)
                cout <<t << "
";
            else
            {
               // cout << 1 << endl;
                for(int i = 0;i<k-1;++i)
                    cout << t[i];
                cout << "
";
            }
        }
    }
    return 0;
}

B. Array Sharpening

题意:

给你一个长度为n的数组,对于每一个大于0的数,你可以把它们减1,问能不能将这个数组构造成单峰数组

思路:

首先,数组中要求存在的最小元素是0,我们可以从左到右枚举,从左到右能构造的最长严格上升子序列的右下标为l,然后再从右往左,从右往左能构造的最长严格下降子序列的左下标为r,假如这两段子序列不相交,即l<r,则输出No,否则输出Yes

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
typedef long long LL;
LL num[maxn];
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i = 0; i<n; i++)
            cin >> num[i];
        int a = 0;
        bool flag = true;
        int l,r;
        for(int i = 0; i<n; ++i,++a)
        {
            if(num[i]<a)
            {
                l = i-1;
                flag = false;
                break;
            }
        }
        if(flag)
        {
            printf("Yes
");
            continue;
        }
        flag = true;
        a = 0;
        for(int i = n-1; i>=0; --i,++a)
        {
            if(num[i]<a)
            {
                r = i+1;
                flag =false;
                break;
            }
        }
      //  cout << l << " " << r << endl;
        if(flag)
        {
            printf("Yes
");
            continue;
        }
        if(l>=r)
        {
            printf("Yes
");
        }
        else
            printf("No
");
    }

    return 0;
}

C. Mind Control

题意:

有个长度为n的数组和n个人,你可以控制其中的k个人,n个人站成一个队列,你是第m个,每个人可以从数组的前面或者后面拿走一个数,问你在最坏的情况下拿到的数是多少,输出这个数。

思路:

首先,你能选择控制的人一定要排在你前面,这样对于结果才能产生作用,接下来排在你前面的人可以分为两种,一种人数是k,另一种的人数是m-1-k,接下来就是轮流从前取数,我们可以枚举从前面取数的人有多少,然后就可以就算出从后面取数的人有多少,然后根据条件更新答案就行

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 4000;
LL num[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m ,k;
        scanf("%d %d %d",&n,&m,&k);
        for(int i= 1;i<=n;++i)
            scanf("%lld",&num[i]);
        k = min(m-1,k);
        int d = m-k-1;
        LL ans = 0;
        //cout << k << " " << d << endl;
        for(int l1 = 0;l1<=k;l1++)
        {
            int r1 = k-l1;
            LL tmp  = 0;
            for(int l2 = 0;l2<=d;l2++)
            {
                int r2 = d-l2;
                int l3 = 1+l1+l2,r3 = n-r2-r1;
                if(tmp==0)
                {
                    tmp = max(num[l3],num[r3]);
                }
                else
                {
                    tmp = min(tmp,max(num[l3],num[r3]));
                }
                //cout << l1 << " " << r1 << " " << l2 << " " << r2 <<  " " << tmp <<endl;
            }
            ans = max(ans,tmp);
            //cout << ans << endl;
        }
        cout << ans << "
";
    }
    return 0;
}

D. Irreducible Anagrams

题意:

对于两个字符串s,t定义一种情况anagrams of each other,表示将s中的字母重新放置以后能够得到t

对于两个满足anagrams of each other的字符串st,假如满足以下条件,则可以称为reducible anagram

条件为存在一个数k(k>=2),并将s划分为k个子串,标为s1……skt划分为k个子串

标为t1……tk,并且子串满足:1.完成划分后子串的相对顺序不能变,即将子串按照下标连接起来以后依然是原先的串。2.对应下标的串siti彼此之间是anagrams of each other

如果不满足上述条件,不满足上述条件,则称为 irreducible anagram上面的定义时建立在stanagrams of each othe

现在给出一个字符串sq次询问

每次询问给出两个数lr,代表从s中截出sl……sr这段子串,问能否找到一个字符串t使得这两段字符串满足 irreducible anagramYes,否No

思路:

首先,我们把截出来的子串表示为k

能想到的是,如果k的长度是1那么一定是Yes,因为无法划分成两个子串。

接下来就是首尾两个字母不同即s[l]!=s[r],那我们只要交换s[l]s[r]就一定是Yes

最后剩下的就是首尾相同情况,此时参照上面的情况,如果k中出现的字母种类大于等于三种,我们就可以找一个最大的j使得s[j]!=s[n],然后与s[j]相同的放在最前面,接下来放与s[n]相同的,剩下的随便放,可以证明,这样的串一定是符合条件的。

前两种情况都比较好判定,第三种情况可以通过前缀和来解决。详情请见代码。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+20;
char s[N];
int n,q,l,r,sum[N][26];
int main()
{
    cin >> (s+1);
    n = strlen(s+1);
    for(int i =1;i<=n;++i)
    {
        for(int j = 0;j<26;++j){
            sum[i][j] = sum[i-1][j];
        }
        sum[i][s[i]-a]++;
    }
    cin >> q;
    while(q--)
    {
        cin >> l >> r;
        int cnt =0;
        for(int i = 0;i<26;++i)
        {
            cnt+=(sum[r][i]-sum[l-1][i]>0);
        }
        if(l==r||cnt>=3||s[l]!=s[r])
        {
            cout << "Yes
";
        }
        else
            cout << "No
";
    }
    return 0;
}

 

以上是关于Codeforces Round #616 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #616 题解

Codeforces Round #616 (Div. 2)

Codeforces Round #616 (Div. 2)

Codeforces Round #616 (Div. 1)

Codeforces Round #616 部分题解

Codeforces Round #616(Div.2) Even But Not Even