CF613C Necklace(字符串 构造)

Necklace

https://ac.nowcoder.com/acm/problem/111227

构造一个环使其成为回文串的切割数最大。

当超过两种颜色的数量为奇数时无法构造出回文串,直接输出。

根据切割的特点,容易想到构造回文串形式的单位循环节,则答案为循环节的数量,其中循环节的最大数量为各颜色数量的 gcd

这里需要分类讨论一下(记各颜色数量的GCD为 d):
(1)循环节中存在奇数数量颜色,循环节个数等于d,结果不可能再大于这个数。
(2)循环节中不存在奇数数量颜色,循环节个数等于d/2,但是还可以从循环节的中间切割,例如 baab baab 切割后为 abba abba,答案乘以2,仍为d。

代码如下:

#include<bits/stdc++.h>
using namespace std;
char s[100005];
int a[26],b[26],n;
int main(){
    scanf("%d",&n);
    int sum=0,cnt=0;
    for(int i=0;i<n;++i){
        scanf("%d",a+i),sum+=a[i]; 
        if(a[i]&1)++cnt;
    }
    if(cnt>1){
        puts("0");
        for(int i=0;i<n;++i){
            char c='a'+i;
            while(a[i]--)putchar(c);
        }
        return 0;
    }
    int d=a[0];
    memcpy(b,a,sizeof b);
    for(int i=1;i<n;++i)
        d=__gcd(d,a[i]);
    printf("%d\n",d); 
    for(int i=0;i<n;++i)b[i]/=d;
    cnt=0;
    for(int i=0;i<n;++i)cnt+=b[i]&1;
    if(cnt>1){
        d/=2;
        for(int i=0;i<n;++i)b[i]*=2;
    } 
    int l=0,r=sum/d-1;
    for(int i=0;i<n;++i){
        char c='a'+i;
        if(b[i]&1){
            s[sum/d/2]=c;
            --b[i];
        }
        cnt=b[i]/2;
        for(int j=0;j<cnt;++j)s[l++]=c,s[r--]=c;
    }
    while(d--)printf("%s",s);
}
全部评论

相关推荐

服从性笔试吗,发这么多笔,现在还在发。
蟑螂恶霸zZ:傻 x 公司,发两次笔试,两次部门匹配挂,
投递金山WPS等公司10个岗位 >
点赞 评论 收藏
分享
10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
11-18 15:57
门头沟学院 Java
最终归宿是测开:这个重邮的大佬在重邮很有名的,他就喜欢打92的脸,越有人质疑他,他越觉得爽😂
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务