5 3 11 10 6 17 8
pwned wow suchproblem manystring soeasy muchlinearalgebra abcdabch
链接 http://acm.hdu.edu.cn/showproblem.php?pid=4850
题意:输出长度为n,长度为4的子串不能重复出现的 小写字母组成的 字符串。
做法:最大长度为4的字符串一共有 26^4个, 如果他们都能连接 如 aaaa 和aaab 可以连接为 aaaab。 如果能都连接的话,最长 长度为26^4+3= 456979。
构造,先把 相同的 构造好, aaaabbbbccccdddd.....yyyyzzzz。把出现过的存在一个4维数组里 如 aaaa,就把dp[0][0][0][0]=1。 如 aazz 就把dp[0][0][25][25]=1;
然后继续构造下一个字母,从最大的字母开始凑接下来一个字母 z不行,因为四个z已经出现过,所以填入y。
这个是这种方法构造出来的 前面一部分的构造结果。
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrsssstttt
uuuuvvvvwwwwxxxxyyyyzzzzyzzyyzyzyyyxzzzxzzyxzyzxzyyxyzzxyzyxyyzxyyxxzzxxzyxxyzxx
yxzxzxyxyxxxzxxxwzzzwzzywzzxwzyzwzyywzyxwzxzwzxywzxxwyzzwyzywyzxwyyzwyyywyyxwyxz
wyxywyxxwxzzwxzywxzxwxyzwxyywxyxwxxzwxxywxxwwzzwwzywwzxwwyzwwyywwyxwwxzwwxywwxwz
经常见到的一类构造问题。这种问题普遍就是 要求 构造一段 长度 然后在这个长度内 某长度的子串没有重复出现。
看了题解,知道了这类题的理论基础是欧拉回路。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <sstream> #define eps 0.00001 #define LL __int64 #define pi acos(-1.0) //456979 set<string>my; char str[457000]; int dp[26][26][26][26]; int main() { str[0]=str[1]=str[2]='a'; string tem; string mat; memset(str,0,sizeof str); memset(dp,0,sizeof dp); for(int i=0;i<26;i++) { for(int j=0;j<4;j++) { str[i*4+j]='a'+i; } } for(int i=3;i<26*4;i++) { dp[str[i-3]-'a'][str[i-2]-'a'][str[i-1]-'a'][str[i]-'a']=1; } for(int i=26*4;i<456979;i++) { for(int j=25;j>=0;j--) { if(dp[str[i-3]-'a'][str[i-2]-'a'][str[i-1]-'a'][j]==0) { dp[str[i-3]-'a'][str[i-2]-'a'][str[i-1]-'a'][j]=1; str[i]=j+'a'; break; } } } int n; while(scanf("%d",&n)!=EOF) { if(n>456979) { printf("Impossible"); continue; } char tem=str[n]; str[n]=0; printf("%s\n",str); str[n]=tem; } return 0; }