Codeforces Round #582 (Div. 3) E. Two Small Strings 题解(构造+图论)

题目链接

题目大意

有两个长度为2的由‘a’ ‘b’ ‘c’三个字母构成的字符串,现在需要构造一个由’a’,‘b’,‘c’,三个字母各n个组成的字符串,且构成的字符串不包含前两个字符串的子串

题目思路

emm。。。。比较神奇
标准题解是说首先生成a、b、c的6个全排列,然后,每种全排列以两种方式扩大n倍——举个例子,n为3时,对于acb,可以扩展成这两种:acbacbacb、aaacccbbb。然后依次检查这12种字符串是否有满足要求的,我一直很疑惑为什么只要这12种构造方法就行了。后面终于搞懂了

证明:
这题是个图论.s,t表示不能走的路.比如,当s="ab“时,表示路径a→b是不通的…因为只有s,t,两个字符串,所以可以得出一个3个顶点,7条边((包括顶点到自己的边))的图…

然后分类讨论:
1:三个顶点都能通过一条边回到自己
这样我们可以构造一种格局使得第一与第二个点联通且第二与第三个点联通,构造出后分别重复n次即可:
举个例子:
3
a b
b c
答案:aaacccbbb

2:三个顶点无法都能通过一条边回到自己::
这样我们可以构造一种格局使得第一与第二个点联通且第二与第三个点联通且第一与第三个点联通,构造出后集体重复n次即可
举个例子::、
3
a a
b c
答案:cbacbacba

代码

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug printf("I am here\n");
using namespace std;
typedef long long ll;
const int maxn=3e5+5,mod=2147493647,inf=0x3f3f3f3f;
int n;
char s1[3],s2[3],s[maxn],per[6][5]={"abc","acb","bac","bca","cab","cba"};
void check(){
    for(int i=1;i<=3*n-1;i++){
        if((s[i]==s1[0]&&s[i+1]==s1[1])||(s[i]==s2[0]&&s[i+1]==s2[1])){
            return ;
        }
    }
    s[3*n+1]='\0';
    printf("YES\n%s\n",s+1);
    exit(0);
}
int main(){
    scanf("%d %s %s",&n,s1,s2);
    for(int i=0;i<6;i++){
        for(int j=1;j<=3*n;j++){
            s[j]=per[i][(j-1+n)%3];
        }
        check();
        for(int j=1;j<=3*n;j++){
            s[j]=per[i][(j-1)/n];
        }
        check();
    }
    printf("NO\n");
    return 0;
}

参考链接:https://www.luogu.com.cn/blog/Guess00/solution-CF1213E

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值