码迷,mamicode.com
首页 > 其他好文 > 详细

CF Round #629

时间:2020-03-28 16:09:31      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:getchar   开始   第一个   表示   字符   没有   etc   src   void   

CF Round #629

A.数学

给定a,b,现在问你最小让a加多少使得a能被b整除,可以为0

即算(b-(a%b))%b

B.数学

给定n和k

问以n-2个a和2个b组成的串中,以字典序升序排列,问第k个是几

这个有点类似康托展开,这个简化了很多

首先考虑第一个b,它处在从左往右数第p位,那么无论第二个b怎么放,它最大是(p-1)*p/2

所以只要找到第一个b为u,第二个b从u-1开始,每往后移一位就小一,找k即可

C.数学

给定n和x

x是一串开头必为2,由0,1,2组成的字符串,一共有n位

现在给定一种计算

技术图片

类似于异或,只不过它mod3

现在问a与b为多少,使得他们进行上述运算得到x,并且max{a,b}最小

解法:

对于a,b而言,为了使他们尽可能的小,则要使得他们相同位上和不能超过3

那么问题就变得简单了

如果没有遇到1,那么a,b将0,2平分,一旦遇到了1,那么a给他1,b给他0,为了使之最小,把x剩下的位全部都塞给b即可

AC:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
#define INF 1e10+5
#define maxn 105
#define minn -105
#define ll long long int
#define ull unsigned long long int
#define uint unsigned int
#define re register
inline int read()
{
	re int t=0;
	re char v=getchar();
	while(v<‘0‘)v=getchar();
    while(v>=‘0‘)
    {
        t=(t<<3)+(t<<1)+v-48;
        v=getchar();
    }
    return t;
}
void solve()
{
    string s;
    ll n;
    cin>>n>>s;
    string s1,s2;
    bool ok=0;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]==‘2‘&&!ok)
        {
            s1=s1+"1";
            s2=s2+"1";
            continue;
        }
        if(s[i]==‘2‘&&ok)
        {
            s2=s2+"2";
            s1=s1+"0";
            continue;
        }
        if(s[i]==‘1‘&&!ok)
        {
            s1=s1+"1";
            s2=s2+"0";
            ok=1;
            continue;
        }
        if(s[i]==‘1‘&&ok)
        {
            s1=s1+"0";
            s2=s2+"1";
            continue;
        }
        s1=s1+"0";
        s2=s2+"0";
    }
    cout<<s1<<endl;
    cout<<s2<<endl;
}
int main()
{
    int t;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        solve();
    }
    return 0;
}

D.模拟

题意:

给定一个环,上面有不同的数

你现在要用k种颜色对他们染色,使得相邻的两个不同数他们染得色不一样

输出最小的k,并且输出染色方案(方案i用i表示,从1开始)

思路:

首先,如果全体一样,那么显然染成一种即可

如果,至少有两种数,并且如果总个数为偶数个,那么1 2交替染即可

如果有奇数个,考虑有没有连续出现的相同的,若有,让他们染一样的,其他照样交替染(注意特例:首尾要特判,可以写在上面那个分类里面)

最后上面什么情况都不满足,那么就是染成三种

1212交替最后一个是3即可

AC:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 1e10+5
#define maxn 200005
#define minn -105
#define ll long long int
#define ull unsigned long long int
#define uint unsigned int
#define re register
int a[maxn];
inline int read()
{
    re int t=0;
    re char v=getchar();
    while(v<‘0‘)v=getchar();
    while(v>=‘0‘)
    {
        t=(t<<3)+(t<<1)+v-48;
        v=getchar();
    }
    return t;
}
void solve()
{
    int n;
    bool ok=0;
    int exist=0;
    n=read();
    for(int i=0;i<n;i++)
    {
        a[i]=read();
        if(i&&a[i]!=a[i-1])ok=1;
        if(i&&a[i]==a[i-1])exist=i;
    }
    if(!ok)
    {
        cout<<1<<endl;
        for(int i=0;i<n;i++)
        {
            cout<<1<<" ";
        }
        cout<<endl;
        return;
    }
    if((!(n&1))||a[0]==a[n-1])
    {
        cout<<2<<endl;
        for(int i=0;i<n;i++)
        {
            if(i&1)cout<<1<<" ";
            else cout<<2<<" ";
        }
        cout<<endl;
        return;
    }
    if(!exist)
    {
        cout<<3<<endl;
        for(int i=0;i<n-1;i++)
        {
            if(i&1)cout<<1<<" ";
            else cout<<2<<" ";
        }
        cout<<3;
        cout<<endl;
        return;
    }
    cout<<2<<endl;
    n-=1;
    for(int i=0;i<n;i++)
    {
        if(i+1==exist)
        {
            if(i&1)cout<<"1 1 ";
            else cout<<"2 2 ";
            continue;
        }
        if(i&1)cout<<1<<" ";
        else cout<<2<<" ";
    }
    cout<<endl;
}
int main()
{
    int t;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        solve();
    }
    return 0;
}

CF Round #629

标签:getchar   开始   第一个   表示   字符   没有   etc   src   void   

原文地址:https://www.cnblogs.com/et3-tsy/p/12587813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!