人生的经验

问题描述

蛤蛤国有一位德高望重的长者,今天是他向HK记者传授一点人生经验的日子。因为长者见得多了,所以长者的人生经验包括长度为l,字符集大小为c的所有字符串。但是HK记者的姿势水平太低,于是长者只好把人生的经验压缩一下。现在长者要你帮他找到一个最短的包含所有人生经验的宇符串,这样才能更好的帮助HK记者学习。
输入格式 (life.in)
第一行是两个正整数c和l,分别表示字符集大小和串长。
第二行是一个长度为c(c≤26)的小写字母字符串,表示人生经验由哪些字符构成。(保证字符串中的字母互不相同)
输出格式 (life.out)
第一行是一个正整数,表示最短母串的长度。
第二行是一个字符串,表示这个最短的母串。如果有多个合法的母串,输出任意一个即可。
样例输入

    2 2
    ab

样例输出

    5
    abbaa

样例说明
长者的人生经验有“aa”、“ab”、“ba”和“bb”,显然长度为8
的字符串“aaabbabb”满足题目要求,但字符串“abbaa”的长度更短。
数据规模与约定
对于10%的数据:c≤3,l≤3
对于另外5%的数据:l=1
对于另外15%的数据:l=2
对于另外35%的数据:输出文件大小不超过1MB
对于100%的数据:输出文件大小不超过10MB

我们可以猜想答案长度是$l+c^{l}-1$

即保证相邻的两个串共用$l-1$个字符

可以建图,有$c^{l}$个顶点

一个点i连向另一个点j经当i的后l-1位等于j的前l-1

即找一条不重复经过点的路径,即哈密顿路,这是NPC的

考虑将点信息转到边

以$c^{l-1}$个前缀为顶点,每个顶点向外连c条边

对于所有$c^{l}$个串,前缀向后缀连边

然后就变成了求边不重复的欧拉路径

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int N=12000005;
 8 int st[N],num[N],ans[N],cnt[N],tot,top,c,l,Mod;
 9 int qpow(int x,int y)
10 {
11     int res=1;
12     while (y)
13     {
14         if (y&1) res=res*x;
15         x=x*x;
16         y/=2;
17     }
18     return res;
19 }
20 void fake_dfs(int x)
21 {int v;
22     st[++top]=x;
23     while (1)
24     {
25         int x=st[top];
26         if (cnt[x]<c) 
27         {
28             ++cnt[x];
29             v=x%Mod*c+cnt[x]-1;
30             st[++top]=v;num[top]=cnt[x]-1;
31             continue;
32         }
33         if (top>1) 
34         {
35             ans[++tot]=num[top];
36             top--;
37         }
38         else break;
39     }
40 }
41 int main()
42 {
43     char ch[31];
44     int i;
45     cin>>c>>l;
46     scanf("%s",ch);
47     cout<<qpow(c,l)+l-1<<endl;
48     if (l==1) cout<<ch<<endl;
49     else 
50     {
51         Mod=qpow(c,l-2);
52         fake_dfs(0);
53         for (i=1;i<l;i++) putchar(ch[0]);
54         for (i=tot;i>=1;i--) putchar(ch[ans[i]]);
55     }
56 }

 

问题描述

蛤蛤国有一位德高望重的长者,今天是他向HK记者传授一点人生经验的日子。因为长者见得多了,所以长者的人生经验包括长度为l

,字符集大小为c

所有字符串。但是HK记者的姿势水平太低,于是长者只好把人生的经验压缩一下。现在长者要你帮他找到一个最短的包含所有人生经验的宇符串,这样才能更好的帮助HK记者学习。

输入格式 (life.in)

第一行是两个正整数c

l

,分别表示字符集大小和串长。

第二行是一个长度为c(c26)

的小写字母字符串,表示人生经验由哪些字符构成。(保证字符串中的字母互不相同)

输出格式 (life.out)

第一行是一个正整数,表示最短母串的长度。

第二行是一个字符串,表示这个最短的母串。如果有多个合法的母串,输出任意一个即可。

样例输入

2 2
ab

样例输出

5
abbaa

样例说明

长者的人生经验有“aa”、“ab”、“ba”和“bb”,显然长度为8

的字符串“aaabbabb”满足题目要求,但字符串“abbaa”的长度更短。

数据规模与约定

对于10%

的数据:c3l3

对于另外5%

的数据:l=1

对于另外15%

的数据:l=2

对于另外35%

的数据:输出文件大小不超过1MB

对于100%

的数据:输出文件大小不超过10MB

posted @ 2018-03-30 21:49  Z-Y-Y-S  阅读(683)  评论(0编辑  收藏  举报