5 3 11 10 6 17 8
pwned wow suchproblem manystring soeasy muchlinearalgebra abcdabch
题意:构造一个长为n的字符串,使得字符串没有两个相同的长度为4的子串,如果无法构造则输出-1.
首先长度为4的不同的串一共有26*26*26*26个,然后末尾加上开头的前三位最多就是26^4+3,可以把每一个
四位子串看成一个节点,然后一个子串可以转移到26种子串,一个子串也可以从26个串转移过来,然后找一条
经过每一个点的路径就是最优解.然后dfs暴搜.
额..由于这个图非常完美的对称性质只要保证每次不搜到搜过的点就可以了(验证了一下并没有回溯).
坑点:HDU的栈太小了用C++扩栈
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <cstdlib> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") #define maxn 26*26*26*26 const int m3 = 26*26*26, m2 = 26*26, m1 = 26; bool vis[maxn+5]; char ans[maxn+5]; bool dfs (int u, int cnt) { if (cnt == maxn) { return 1; } for (int i = 0; i < 26; i++) { int v = u%m3; v = v*26+i; if (vis[v]) continue; vis[v] = 1; ans[cnt+3] = i+'a'; if (dfs (v, cnt+1)) return 1; vis[v] = 0; } return 0; } int main () { memset (vis, 0, sizeof vis); ans[0] = ans[1] = ans[2] = ans[3] = 'a'; vis[0] = 1; dfs (0, 1); int n; while (scanf ("%d", &n) == 1) { if (n > maxn+3) printf ("Impossible\n"); else { for (int i = 0; i < n; i++) printf ("%c", ans[i]); printf ("\n"); } } return 0; }