CF Round #629
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;
}