构造题就是这样,总是让人埋怨当初太SB。。
首先,要注意这里字符串最长为26^4+3,因为一共有26^4个不同的字符串,每个串占用一个开头,+3是最后的那个串末尾的三个。
然后以aaaabbbbcccc....为开头枚举,先枚举26*4个,之后对每一位从a~z,看能否放这个letter(如果没有前面的26*4个string,这个过程中是不会出现XXXX型的,具体原因木有想清楚,%>_<%,可能和len++后填的下一位数是从X之后开始的有关?),这样枚举的总数也正好是26^4+3
#include<iostream> #include<stdio.h> #include<cstdio> #include<stdlib.h> #include<vector> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<queue> #include <ctype.h> #include<map> #include<time.h> #include<bitset> using namespace std; //hdu 4853 const int maxn=500010; int vis[26][26][26][26]; int str[maxn]; int n; int len; void init() { memset(vis,0,sizeof(vis)); len=0; for(int i=0;i<26;i++) { //vis[i][i][i][i]=1; 不是四个四个一组标记为1,这种case只能标记 1234=1 5678=1,少了2345=1,3456=1这种 str[len]=str[len+1]=str[len+2]=str[len+3]=i; len+=4; } for(int i=0;i<len-3;i++) { vis[str[i]][str[i+1]][str[i+2]][str[i+3]]=1; } while(true) { bool flg=true; //int cnt=0; for(int i=0;i<26;i++) { if(!vis[str[len-3]][str[len-2]][str[len-1]][i]) { //if(str[len-3]==str[len-2]&&str[len-1]==str[len-2]&&str[len-1]==i) cout<<i<<" "<<(cnt++)<<endl; 枚举不到XXXX这种 vis[str[len-3]][str[len-2]][str[len-1]][i]=1; str[len]=i; len++; flg=false; } } if(flg) break; } // cout<<len<<endl; } int main() { freopen("input.txt","r",stdin); //freopen("data.txt","r",stdin); //freopen("out1.txt","w",stdout); //cout<<pow(26,4)+3<<endl; init(); while(scanf("%d",&n)!=EOF) { if(n>len) printf("Impossible\n"); else { for(int i=0;i<n;i++) { printf("%c",'a'+str[i]); } printf("\n"); } } return 0; }