Codeforces Round #629 Div. 3
A. Divisibility Problem
题意:
给定两个数a,b,每次可以对a进行加1操作,最少几次操作后a可以整除b
解题思路:
求大于等于a的最小b的整倍数:
- 若a%b==0, 直接输出a
- 若a%b!=0,a/b向上取整*b
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b;cin>>a>>b;
int x=a/b,res;
if(a%b==0)
res=0;
else res=(a/b+1)*b-a;
cout<<res<<endl;
}
}
B. K-th Beautiful String
2. B. K-th Beautiful String
题意:
长度为n的字符串包含n−2个a和2个b,求按照字典序排列输出第k个字符串
解题思路:
该字符串字典序排序仅取决于b,通过找规律找到b的位置规律:
- b1在倒数第二位有1种情况(第一组),在倒数第三位有2种情况(第二组)…在倒数第n位时有n−1种情况(n-1组),对此分组,通过累加情况和找出b1位于哪一组
- b2在b1所在组i中逆序移动,n->n-i+1
- K–(累加情况和–b1所在组情况数)为b2在字符串中逆序数位数
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--)
{
ll n,k;
cin>>n>>k;
ll x=0,y,t=0;
for(int i=1;i<=n;i++)
{
t+=i;
if(t>=k&&(t-i)<k)
{
x=n-i;y=n-(k-(t-i))+1;
}
}
for(int i=1;i<=n;i++){
if(i==x||i==y) cout<<"b";
else cout<<"a";
}
cout<<endl;
}
}
C. Ternary XOR
3. C. Ternary XOR
题意:
三进制数c由三进制的数a和b通过操作
ci=(ai+bi)%3获得
给定c求出a和b并使得max(a,b)最小(c的三进制数首位保证为2)
解题思路:
对c的每一位进行操作分给a,b:(设a为较大数)
(flag=1标志a,b开始有大小之分)
- 若ci=0:ai=0,bi=0
- ci=2且flag=0:均分ai=1,bi=1;
- 若c1=1且flag=0:ai=1,flag=1,此刻起a为max(a,b),使max最小,此后a均为0,bi=ci;
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[50005],b[50005],c[50005];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n,flag=0;scanf("%d",&n);char s;getchar();
for(int i=0;i<n;++i)
{
scanf("%c",&s);
c[i]=s-'0';
}
for(int i=0;i<n;++i)
{
if(c[i]==0)
{
a[i]=0;b[i]=0;
}
if(c[i]==1)
{if(flag==0)
{
a[i]=1;b[i]=0;flag=1;
}
else {
a[i]=0;b[i]=1;
}
}
if(c[i]==2)
{
if(flag==0) {a[i]=1;b[i]=1;
}
else {
a[i]=0;b[i]=2;
}
}
}
for(int i=0;i<n;++i)
printf("%d",a[i]);
printf("\n");
for(int i=0;i<n;++i)
printf("%d",b[i]);
printf("\n");
}
}
D. Carousel
4. D. Carousel
题意:
n个木马围成一个圈,为每个属性为t[i]的木马上色,要求:任何相邻且种类不同的木马颜色不同,种类相同的木马颜色随意,求最少需要颜色数,并输出涂色方案
解题思路:
- 当所有元素相同时,上同一种颜色,全部输出1
- 当n为偶数时,只需要两种颜色,以1,2,1,2⋯1,2 循环
- n为奇数时,如果所有相邻的种类都不同,前n−1个数以1,2,1,2⋯循环输出,最后输出一个3
若有两个相邻的元素相等,将两个元素上同一中颜色,元素合并,即为n-1偶数个元素以1,2,1,2⋯循环上色
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n,flag=0;scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&a[i]);
if(i!=0&&a[i]!=a[i-1])
flag=1;
}
if(flag==0)
{printf("1\n");
for(int i=0;i<n;++i)
printf("1 ");
printf("\n");
}
else
{
a[n]=a[0];
if(n%2==0)
{printf("2\n");
for(int i=0;i<n;++i)
{
if(i%2)
printf("1 ");
else printf("2 ");
}printf("\n");
}
else
{int pos=-1;
for(int i=0;i<n;++i)
{
if(a[i]==a[i+1])
{
pos=i;break;
}
}
if(pos!=-1)
{flag=0;printf("2\n");
for(int i=0;i<n;++i)
{
if(!flag)
{printf("1 ");flag=1;
}
else{
printf("2 ");flag=0;
}
if(i==pos)
{
if(flag==0) flag=1;
else flag=0;
}
} printf("\n");
}
else{
printf("3\n");
for(int i=0;i<n-1;++i)
printf("%d ",i%2+1);
printf("3\n");
}
}
}
}
}
E. Tree Queries
5. E. Tree Queries
题意:
给你一棵以 1 为根节点的树,树是一个具有n-1的连通无向图,n-1条边,q次查询,对每次查询的 k个点:是否有一条从根(1)到某个顶点u的路径,使得每个给定的k个顶点要么属于该路径,要么与该链上一个点的距离为1,存在输出YES,否则输出NO
解题思路:
找到该数列中深度最大的点b,要想所有点在一条线上,必须要让其他点的祖先都和b是一个公共祖先,限制其他点到这条线的距离小于1,即a节点的父节点在这条线上。
代码: