题意:构造一个长度为N的小写字母字符串,要求所有长度大于等于4的子串只能出现一次。不能构造输出“Impossible”。
思路:详见:点击打开链接
类似的字符串构造题应该也能抽象出类似的模型。
另一种写法:点击打开链接
代码:
#include<bits/stdc++.h>
#define MAXN 26 * 26 * 26
#define mod (26 * 26)
using namespace std;
struct node{
int now, ch;
node(int _now = 0, int _ch = 0) : now(_now), ch(_ch) {}
}st[500050];
int get_next(int now, int i)
{
return (now % mod) * 26 + i;
}
/*
void dfs(int now)//递归版,非递归版不好理解可以对照着递归版的写
{
for(int i = cur[now]; i < 26; i++)
{
if(vis[now][i]) continue;
vis[now][i] = 1;
cur[now] = i + 1;
dfs(get_next(now, i));
ans[top++] = i + 'a';
}
}
*/
int cur[MAXN], tot;
bool book[MAXN][26];
char ans[500050];
void init()
{
int now = 0, top = 0;
while(1)
{
bool flag = 0;
for(int i = cur[now]; i < 26; i++)
{
if(book[now][i]) continue;
flag = book[now][i] = 1;
cur[now] = i + 1;
now = get_next(now, i);
st[++top] = node(now, i);
break;
}
if(!flag){
ans[tot++] = st[top].ch + 'a';
now = st[--top].now;
}
if(!top) break;
}
for(int i = 0; i < 3; i++)
ans[tot++] = 'a';
}
int main()
{
init();
int n;
char ch = 0;
while(~scanf("%d", &n))
{
if(n > tot) puts("Impossible");
else{
swap(ch, ans[n]);
puts(ans);
swap(ch, ans[n]);
}
}
return 0;
}