http://acm.hdu.edu.cn/showproblem.php?pid=4850
题意:构造长度为n的字符序列,使得>=4的子串只出现一次
其实最长只能构造出来26^4+4-1= 456979 的序列,大于该数的都是不可能的。构造方法,就是那种欧拉回路的序列,此题DFS会爆栈,手动扩展栈也可以AC......
递归形式的开始WA了,没有细调就换非递归了,后来又想了想,虽然自己电脑上运行不了,但是先把长度按小的来,然后调试代码,然后在扩大,AC了,当时错在MOD,递归的MOD应该是26^4,而不是26^4+1,因为控制在0~(26^4-1)范围内,就是456976个数
所以要变成非递归,我其实不太理解非递归的,然后参考自己以前做过的也是不太理解的这个代码http://blog.csdn.net/u011026968/article/details/38151303
然后AC
非递归版 46ms AC
//#pragma comment(linker, "/STACK:102400000,102400000")
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 100000000;
const int MAXN = 101;
const int S = 500000;
const int SIZE = 26;
const int LEN = 456976+3;
//const int MOD = 456976;
const int MOD =17576;
char str[LEN+10];
char li[LEN*SIZE+10];
int sta[LEN*SIZE+10];
/*int dfs(int cnt, int s)
{
//printf("cnt=%d %d\n",cnt,s);
if(cnt == LEN)return 1;
for(int i=0;i<SIZE;i++)
{
if(!vis[(s*SIZE+i)%MOD])///
{
vis[(s*SIZE+i)%MOD]=1;
str[cnt]=i;
if(dfs(cnt+1, (s*SIZE+i)%MOD))return 1;
//vis[(s<<1)+i]=0;
}
}
return 0;
}*/
int tp,ans;
void sea(int v)
{
while(li[v]<SIZE)
{
int w=v*SIZE+li[v];
li[v]++;
sta[tp++]=w;
v=w%MOD;
}
}
void solve()
{
CL(str,0);
CL(li,0);
tp=0;
int v;
sea(0);
str[0]='a';
ans=1;
while(tp)
{
v=sta[--tp];
str[ans++]=v%SIZE+'a';
v/=SIZE;
sea(v);
}
}
int main()
{
//OUT("hdu4850.txt");
solve();
int n;
while(~scanf("%d",&n))
{
if(n>LEN)puts("Impossible");
else
{
if(n<=4)
{
for(int i=0;i<n;i++)
putchar('a');
}
else
{
for(int i=1;i<4;i++)putchar('a');
int tt=ans;
n-=3;
while(tt>ans-n)putchar(str[--tt]);
}
putchar('\n');
}
}
return 0;
}
递归版 93ms AC
#pragma comment(linker, "/STACK:102400000,102400000")
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 100000000;
const int MAXN = 101;
const int S = 500000;
const int SIZE = 26;
const int LEN = 456976+3;
const int MOD = 456976;
int str[LEN+10];
int vis[LEN+10];
int dfs(int cnt, int s)
{
//printf("cnt=%d %d\n",cnt,s);
if(cnt == LEN)return 1;
for(int i=0;i<SIZE;i++)
{
if(!vis[(s*SIZE+i)%MOD])///
{
vis[(s*SIZE+i)%MOD]=1;
str[cnt]=i;
if(dfs(cnt+1, (s*SIZE+i)%MOD))return 1;
}
}
return 0;
}
void init()
{
CL(str,0);
CL(vis,0);
vis[0]=1;
dfs(4,0);
}
int main()
{
//OUT("hdu4850.txt");
init();
int n;
while(~scanf("%d",&n))
{
if(n>LEN)puts("Impossible");
else
{
for(int i=0;i<n;i++)
putchar(str[i]+'a');
putchar('\n');
}
}
return 0;
}