Educational Codeforces Round 78 (Rated for Div. 2) --补题

Posted crossea

tags:

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

技术图片
技术图片
链接

直接用数组记录每个字母的个数即可

#include<bits/stdc++.h>

using namespace std;

int a[26] = {0};
int b[26] = {0};

int judge()
{
    //cout<<"111"<<endl;
    for (int i = 0; i < 26; ++i)
    {
        if (a[i]!=b[i])
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    //ios::sync_with_stdio(false);
    int t;
    cin>>t;
    char p1[101],p2[101];
    int flag = 0;
    while(t--)
    {
        cin>>p1;
        cin>>p2;
        flag = 0;
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        int len = strlen(p1);
        if (len >strlen(p2))
        {
            cout<<"NO"<<endl;
            continue;
        }
        else
        {
            for (int i = 0; i < len; ++i) //先算出一个值
            {
                a[p1[i]-'a'] ++;
                b[p2[i]-'a'] ++;
            }
            
            for (int i = 0; i<(strlen(p2)-strlen(p1)); ++i)
            {
                // for (int i = 0; i < 26; ++i)
                // {
                // cout<<b[i]<<endl;
                // }
                if(judge())
                {
                    flag = 1;
                    break;
                    //cout<<"111"<<endl;
                }
                else{
                    b[p2[i]-'a'] -= 1;
                    b[p2[i+len]-'a'] += 1;
                    //cout<<p2[i]<<endl;
                }
                
            }
        
        }
        if (judge())
        {
            flag = 1;
        }
        if (flag)
            {
                cout<<"YES"<<endl;
            }
        else
            cout<<"NO"<<endl;
    }

    return 0;
}

技术图片
技术图片
链接

一直给小的数加,直到大于等于大的那个数,这个时候就可能出现这种情况
1. 超过了一个偶数(0也算)
2. 超过了一个奇数,当前加到的数是奇数
3. 超过了一个奇数,当前加的是偶数
分析可以发现,如果超过了一个偶数,肯定可以从前面加的数里面取这个数的一半的那个数来调平。所以次数就是i
但是如果超过的是奇数,那么是不可能调平的,因为奇数不可能分解成相等的整数(可以思考一下,我们只需要调平超出的数就行)
所以分析可知,必须使得超出的数是偶数,那么此时如果i是奇数,结果就是i+2, i是偶数结果就是i+1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
 
    int t;
    cin >> t;
    while(t--){
        ll a,b;
        cin >> a >> b;
        if(a < b) {
            swap(a, b);
        }
        ll c = a - b;
        int i = 0;
        ll s = 0;
        if(c==0)
        {
            cout<<0<<endl;
            continue;
        }
        while(1){
            i++;
            s = i * (i + 1) / 2;
            if(s < c) {
                continue;
            }
            else
            {
                if((s-c)&1)
                {
                    if(i&1)
                    {
                        cout<<i+2<<endl;
                        break;
                    }
                    else
                    {
                        cout<<i+1<<endl;
                        break;
                    }
                }
                else
                {
                    cout<<i<<endl;
                    break;
                }
            }
        }
    }
 
}

技术图片
技术图片
技术图片

链接

分前半段和后半段求前缀和,对前半段预处理后。遍历后半段的去找最小值。
#include<bits/stdc++.h>

using namespace std;

int a[200000];
int b[400000];
int vis[400000];

int main(int argc, char const *argv[])
{
    int t;
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        memset(b, 0x3f, sizeof(b));
        memset(vis,0,sizeof(vis));
        int count = 0;
        for (int i = 1; i<=n; ++i)
        {
            cin>>a[i];
            a[i] = a[i]==2? -1:1;
            count += a[i];
        } //记录下来了
        a[n+1] = 0;
        b[200000] = 0;
        vis[200000] = 1;
        for (int i = n; i >=1; --i) //前缀和,前半部分是要倒着求得
        {
            a[i] += a[i+1];
            if(!vis[200000+a[i]]) //记录下到达每个位置的最近的放步数
            {
                vis[200000+a[i]] = 1;
                //cout<<200000+a[i]<<" "<<n-i+1<<endl;
                b[200000+a[i]] = n-i+1; //给他赋值,记录最快速到达的放法
            }
        }
        a[0] = 0;
        for (int i = 1; i <= n; ++i)
        {
            cin>>a[i];
            a[i] = a[i] == 2? -1:1;
            count += a[i];
            a[i] += a[i-1]; //后半部分正着求前缀和
        }
        int mi = b[200000+count]; //表示全部从左边取
        for (int i = 1; i <= n; ++i)
        {
            //cout<<mi<<endl;
            mi = min(mi, b[count-a[i]+200000]+i);
        }
        if (count)
        {
            cout<<mi<<endl;
        }
        else
        {
            cout<<0<<endl;
        }
    }
    return 0;
}

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

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27