Codeforces Round #629(Div.3)

30 篇文章 0 订阅

A题:

题意:给你两个数a和b,每次可以让a=a+1,问你最少需要多少次,可以使a能被b整除。
思路:这道题的话,大水题,看代码吧。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll a,b;
        cin>>a>>b;
        if(a%b==0)
            cout<<"0"<<endl;
        else
        {
            ll x=a/b;
            x++;
            cout<<x*b-a<<endl;
        }
    }
    return 0;
}

 

B题:

题意:给你一个长度为n的字符串,其中前n-2项为a,后2项为b,不难发现,按照字典序对这个字符串进行排序的话,共有n*(n-1)/2种不同的排序,现在给你一个数k,问你在这n*(n-1)/2种排序中,第k种是啥。
思路:这道题的话,也是一道水题,直接看代码吧。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        int ans=1;
        while(k>ans)
        {
            k-=ans;
            ans++;
        }
        ans++;
        int a=k;
        for(int i=n; i>=1; i--)
        {
            if(i==ans || i==a)
                cout<<"b";
            else
                cout<<"a";
        }
        cout<<endl;
    }
    return 0;
}

 

C题:

题意:如果一个数字只包含0、1和2,那么它就是三元的。你有一个很长的三进制数字x, x的第一个(最左边的)数字保证是2,x的其他数字可以是0、1或2。我们定义两个长度为n的三进制数a和b的三进制异或运算⊙为一个长度为n的数c=a⊙b。其中ci=(ai+bi)%3(其中%为模运算)。换句话说,将相应的数字相加,然后取余数除以3。例如,10222⊙11021=21210。你的任务是找到这样的三进制数字a和b,长度都是n,并且都没有前导零,使得a⊙b=x,并且最大值(a,b)是最小的可能。
思路:这道题的话,很容易能看出来是贪心。当第一次出现1之前,2的话各分配1,0的话都是0;当第一次出现1的时候,给a分配1,b分配0;之后所有的数都分配给b,a都是0即可。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
string s;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cin>>s;
        string a="",b="";
        a+='1';
        b+='1';
        int flag=1;
        for(int i=1; i<n; i++)
        {
            if(flag)
            {
                if(s[i]=='0')
                {
                    a+='0';
                    b+='0';
                }
                else if(s[i]=='2')
                {
                    a+='1';
                    b+='1';
                }
                else if(s[i]=='1')
                {
                    a+='1';
                    b+='0';
                    flag=0;
                }
            }
            else
            {
                a+='0';
                b+=s[i];
            }
        }
        cout<<a<<endl<<b<<endl;
    }
    return 0;
}

 

D题:

题意:圆形的旋转木马由n个动物形象组成。数字按旋转木马的移动顺序从1到n编号。这样,在第n个图之后,数字1的图就跟在后面了。每个图形都有自己的类型——对应于这个图形的动物类型(马、老虎等等)。第i个图形的动物类型为ti。你想用其中一种颜色给每个人物上色。你的任务是给图形上色,使使用的不同颜色的数量尽可能少,不存在不同类型的图形一个接一个地用同一种颜色上色。如果使用k种不同的颜色,那么数字的颜色应该用从1到k的整数表示。
思路:这道题的话,需要分情况讨论,在分析样例的过程中,不难发现,最多只需要3种颜色即可。然后我们分析,当每个木马都相同的时候,k=1;当木马不同的时候,我们可以用贪心的策略,因为题目要求相邻的类型不同的颜色不同,我们直接让所有的奇数项为2,偶数项为1,然后我们再判断首项和末项是否冲突。如果此时n为偶数,首项为2,末项为1,不冲突;如果n为奇数,那就要让其中一对相邻的数涂同样的颜色,其他照旧21212121循环即可,此时注意特判开头和结尾相同的情况。如果没有任意一对相邻的数相同,直接输出212121…3即可。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
int a[maxx];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int ans=0;
        int temp;
        int flag=1;
        for(int i=1; i<=n; i++)
        {
            cin>>a[i];
            if(a[i]==a[i-1])
                ans=i-1;
            if(i==1)
                temp=a[1];
            if(a[i]!=temp)
                flag=0;
        }
        if(flag)
        {
            cout<<"1"<<endl;
            for(int i=1; i<=n; i++)
                cout<<"1"<<" ";
            cout<<endl;
        }
        else if(a[1]==a[n] || n%2==0)
        {
            cout<<"2"<<endl;
            for(int i=1; i<=n; i++)
                cout<<(i%2)+1<<" ";
            cout<<endl;
        }
        else if(ans==0)
        {
            cout<<"3"<<endl;
            for(int i=1; i<=n-1; i++)
                cout<<(i%2)+1<<" ";
            cout<<"3"<<endl;
        }
        else
        {
            cout<<"2"<<endl;
            for(int i=1; i<=ans; i++)
                cout<<(i%2)+1<<" ";
            for(int i=ans+1; i<=n; i++)
                cout<<(i+1)%2+1<<" ";
            cout<<endl;
        }
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值