题意: 给定一个n,要求输出一个长度为n的字符串,并且不会有长度大于等于4的重复的子串,不能得到输出impossible。
题解: 这题就跟POJ1780 Code——欧拉回路(非递归DFS)很像。无非这里变成了字符串处理起来烦一点点 ,也就亿点点。
- 构造。 当然了,能重复的子串长度不能超过3,已经可以写一个很长很长的字符串了,当然是先构造好一个条件允许下最长的字符串,然后输出要求长度就行了。
- 点。 既然是欧拉回路的问题,点是什么,是构造到当前位置时,前三位字母构成的字符串。
- 边。 所有的点,后面都能跟上26种字母,即
a~z
,这26种可能,就是边。
如果代码看起来晦涩难懂,可以先看我的另一篇博客POJ1780 Code——欧拉回路(非递归DFS),几乎是用一模一样的办法解决。
过程中犯的错:
- zaaa: solve函数末,给
ans[]
的末尾又加上了zaaa
,这是构造过程中不可避免的缺陷,需要后期手动补上。
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, len = 3;
char ans[N] = "aaa";
map<string, int> deg;
void solve(){
string pre = "aaa";
while(deg[pre] < 26){
char add = deg[pre] + 'a';
deg[pre]++;
if(deg[pre.substr(1, 2) + add] == 26) continue;
ans[len++] = add;
pre = pre.substr(1, 2) + add;
}
ans[len++] = 'z', ans[len++] = 'a', ans[len++] = 'a', ans[len++] = 'a';
// cout << len << ans << endl;
}
int main(){
solve();
while(~scanf("%d", &n)){
if(n > len) printf("Impossible\n");
else{
for(int i = 0; i < n; i++)
printf("%c", ans[i]);
printf("\n");
}
}
return 0;
}