其他分享
首页 > 其他分享> > Codeforce Round #640 Div4

Codeforce Round #640 Div4

作者:互联网

Codeforce Round #640 Div4

一直听说cf之前搞过一场div4,所以找了个时间vp了一下,题目还是挺有意思的,感觉全是构造题。不知道为啥后来不办了,vp虚拟rank进了前30,前面写的有点慢,写简单题的速度还得在练练,简单写个题解把

A.Sum of Round Numbers

题意就是给你一个数,拆分成几个数,让拆分后的数都只有第一位不为0,感觉我写的有点麻烦了

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll t,n;

int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        ll cnt=0,ans=0;
        ll nn=n;
        while(nn)
        {
            if(nn%10)ans++;
            nn/=10;
        }
        cout<<ans<<"\n";
        while(n)
        {
            if(n%10)
            {
                cout<<n%10;
                for(int i=1;i<=cnt;i++)
                cout<<'0';
                cout<<" ";
            }
            n/=10;
            cnt++;
        }
        cout<<"\n";
    }
    return 0;
}

B.Same Parity Summands

给你n和k问n能不能拆分成k个全为奇数或全为偶数的数,简单考虑拆奇数或偶数,前k-1个都按最小单位拆,也就是1或2,这样不影响最后一个数的奇偶性,然后看最后剩下的数满不满足奇偶性要求

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll n,t,k;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        if(n>=k)
        {
            if((n-(k-1))&1)
            {
                cout<<"YES"<<"\n";
                for(int i=1;i<k;i++)
                cout<<1<<" ";
                cout<<n-k+1<<"\n";
            }
            else if(n>=2*k&&(n-(2*k-2))%2==0)
            {
                cout<<"YES"<<"\n";
                for(int i=1;i<k;i++)
                cout<<2<<" ";
                cout<<(n-(2*k-2))<<"\n";
            }
            else cout<<"NO"<<"\n";   
        }
        else cout<<"NO"<<"\n";
    }
    return 0;
}

C. K-th Not Divisible by n

找到第k个不整除与n的数

不断模拟,然后是n的倍数跳过,加上模数继续算,知道不用跳过,答案就是要跳过的个数+k

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll t,n,k;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        ll kk=k,ans=0,tmp=0;
        while(kk)
        {
            kk+=tmp;
            ans+=kk/n;
            tmp=kk%n;
            kk=kk/n;
        }
        cout<<k+ans<<"\n";
    }
    return 0;
}

D. Alice, Bob and Candies

按题目要求模拟拿取过程即可,基础模拟题

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll t,n,a[1010];
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        ll cnt=0,cnta=0,cntb=0,nowa=0,nowb=0,now=0,hh=1;
        for(int l=1,r=n;l<=r;)
        {
            if(hh&1)
            {
                while(1)
                {
                    if(l>=r+1)break;
                    nowa+=a[l];
                    cnta+=a[l];
                    l++;
                    if(nowa>now)
                    {
                        now=nowa;
                        nowa=0;
                        break;
                    } 
                } 
            }
            else {
                while(1)
                {
                    if(l>=r+1)break;
                    nowb+=a[r];
                    cntb+=a[r];
                    r--; 
                     if(nowb>now)
                    {
                        now=nowb;
                        nowb=0;
                        break;
                    }
                }
            }
            hh++;
 
        }
        cout<<hh-1<<" "<<cnta<<" "<<cntb<<endl;
    }
    return 0;
}

E. Special Elements

这题关键在空间不够,只给了64Mb所以map不能用,还可以用前缀和数组代替a数组省点空间。

之后就很简单,处理出所有前缀和能处理的区间,记录下8000以内这个数有没有出现过,最后统计下就行

刚开始以为要输出每对l r想用map存,mle了一发

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int t,n,x,s[8010];
int mp[8010];
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            mp[i]=0;
            cin>>x;
            s[i]=s[i-1]+x;
        }
        for(int i=1;i<n;i++)
        for(int r=i+1;r<=n;r++)
        {
            if(s[r]-s[i-1]<=8000)
            {
                mp[s[r]-s[i-1]]=1;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(mp[s[i]-s[i-1]])

            ans++;
        }
        cout<<ans<<"\n";
    }
    return 0;
}

F. Binary String Reconstruction

挺有意思的一个构造题

告诉你一个01串中相邻两位和为0的个数n0,为1的个数n1和为2的个数n2,让你构造一个01串,容易发现,字符串长度固定,因为不管每一位放啥,都一定会产生一个和,那么考虑其实没区别,分开处理每种情况就行,先搞n0+1个0完成题目n0个和为0的构造,然后在n2+1个1完成1的构造,注意0和1交接处必然产生了一个和为1的组合,由于题目保证有结果,那么如果n1小于1,n0或n2肯定有一个0,不输出即可,对于和为1的,我们还要在构造n1-1个,在串的末尾交替添加01,每添加一个和为1的数就多一个,然后解决了问题

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll t,n0,n1,n2;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n0>>n1>>n2;
        if(n1==0)
        {
            if(n0)
            for(int i=0;i<=n0;i++)
                cout<<0;
            else  
            for(int i=0;i<=n2;i++)
                cout<<1;
        }
        else {
            for(int i=0;i<=n0;i++)
            cout<<0;
            for(int i=0;i<=n2;i++)
            cout<<1;
            n1=n1-1;
            ll fl=0;
            for(int i=1;i<=n1;i++)
            {
                cout<<fl;
                fl=1-fl;
            }
        }
        cout<<"\n";
    }
    return 0;
}

G. Special Permutation

也是个构造题,让你构造一个排列,满足任意两位的差在2-4之间。n小于3显然无解,刚开始没想清楚,后来发现了一种通解形式。从最大的奇数每次下降2到1为止,然后对于1,用4 2在交界处处理下,之后如果还有在加到6继续正常输出即可

奇偶各给出了一个例子

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll t,n;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        if(n<=3)cout<<"-1"<<"\n";
        else
        {
            if(n&1)
            {
                for(int i=0;i<n/2+1;i++)
                {
                    cout<<n-2*i<<" ";
                }
                cout<<4<<" "<<2<<" ";
                for(int i=0;i<(n/2)-2;i++)
                cout<<6+i*2<<" ";
            }
            else {
                for(int i=0;i<n/2;i++)
                {
                    cout<<n-1-2*i<<" ";
                }
                cout<<4<<" "<<2<<" ";
                for(int i=0;i<(n/2)-2;i++)
                cout<<6+i*2<<" ";
            }
            // 3 1 4 2
            // 5 3 1 4 2 6
           
            cout<<endl;
        }
    }
    return 0;
}

标签:int,ll,cin,long,640,while,Codeforce,using,Div4
来源: https://www.cnblogs.com/tscjj/p/16057585.html