ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-12-20 17:57:55  阅读:302  来源: 互联网

标签:200000 Educational Rated 奇数 int cin 偶数 vis 补题




链接

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

#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;
}

标签:200000,Educational,Rated,奇数,int,cin,偶数,vis,补题
来源: https://www.cnblogs.com/Crossea/p/12074386.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有