题目
题意:
要求生成一个字符串,字符集是前m个字母,长度为n,要求包含的最长回文子串最短,多组解输出字典序最小的。
题解:
1、m==1时,输出n个a。
2、m>2时,将“abc”循环输出。
3、m==2时:打表找一下规律,当n>8的时候,可以看到开头一定是"aa",然后"aababb"循环。如果最后出现的“bb”后的字符不多于4,则将他们都替换成“a”。
在做这题时,对于第三种情况想得太简单。后来想到循环节应该是"aababb",开头可以是多个“a”,但是又没想到结尾也可以是多个“a”。早应该打表的。
//Time:0ms //Memory:400KB //Length:1885B #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define MAXN 100010 char str[MAXN],ans[MAXN],tstr[MAXN],tans[MAXN]; int mlen; void dfs(int h,int top)//打表…… { if(h==top) { int tmp=1; for(int i=0;i<top;++i) for(int j=i+tmp;j<top;++j) { bool flag=true; for(int l=i,r=j;l<r&&flag;l++,--r) if(tstr[l]!=tstr[r]) flag=false; if(flag) tmp=max(j-i+1,tmp); } if(mlen>tmp) mlen=tmp,strcpy(tans,tstr); else if(mlen==tmp&&strcmp(tstr,tans)<0) strcpy(tans,tstr); } else { tstr[h]='a'; dfs(h+1,top); tstr[h]='b'; dfs(h+1,top); } } int main() { //freopen("/home/moor/Code/input","r",stdin); int ncase,n,m; scanf("%d",&ncase); for(int hh=1;hh<=ncase;++hh) { scanf("%d%d",&m,&n); printf("Case #%d: ",hh); if(m==1) for(int i=0;i<n;++i) printf("%c",'a'); else if(m==2) { if(n<9) { mlen=100; dfs(0,n); tans[n]='\0'; printf("%s",tans); } else { ans[0]='a',ans[1]='a'; for(int i=2;i<n;i+=6) strcpy(&ans[i],"aababb"); ans[n]='\0'; int len=n-1; while(ans[len]!='b'||ans[len-1]!='b') --len; if(len>=n-5) for(int i=len+1;i<n;++i) ans[i]='a'; printf("%s",ans); } } else { m=3; for(int i=0,j=0;i<n;++i,j=(j+1)%m) printf("%c",'a'+j); } printf("\n"); } return 0; }