题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4731
题目大意:
给一个n表示有n种字母(全部小写),给一个m,求一个由不超过n种字母组成的m个小写字母的串S,使得S在所有的满足要求的串中最长的回文子串长度最短。
解题思路:
显然当n>=3时肯定是abcabc这样构造。
当n=1时为aaaaaa...
当n=2时,打表可以发现规律。当m>=9时,都满足开始为aaaa,后面为以babbaa作为循环节的串。
打表截图:
压缩暴力打表代码:
char ans[25],temp[25]; int Max; int Cal(char * a,int len) { int res=1; for(int i=0;i<len;i++) { int j; for(j=1;i-j>=0&&i+j<len;j++) if(a[i-j]!=a[i+j]) break; if(j*2-1>res) res=j*2-1; int aa=i,bb=i+1; while(aa>=0&&bb<len) { if(a[aa]!=a[bb]) break; aa--,bb++; } if((i-aa)*2>res) res=(i-aa)*2; } return res; } void dfs(int cur,int len) { if(cur>len) { temp[len]='\0'; int cnt=Cal(temp,len); if(cnt<Max) { strcpy(ans,temp); Max=cnt; } else if(cnt==Max) { if(strncmp(temp,ans,len)<0) strcpy(ans,temp); } return ; } temp[cur]='0'; dfs(cur+1,len); temp[cur]='1'; dfs(cur+1,len); } int main() { for(int i=1;i<=20;i++) { Max=INF; dfs(0,i); for(int j=0;j<i;j++) putchar(ans[j]-'0'+'a'); putchar('\n'); } return 0; }
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #define eps 1e-6 #define INF 0x3fffffff #define PI acos(-1.0) #define ll __int64 #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; char temp[10][10]={"","a","ab","aab","aabb","aaaba","aaabab", "aaababb","aaababbb"}; char ba[7]="babbaa"; int main() { int t,n,m; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { scanf("%d%d",&n,&m); printf("Case #%d: ",ca); if(m<=n) { for(int i=0;i<m;i++) putchar('a'+i); } else { if(n==1) { for(int i=0;i<m;i++) putchar('a'); } else if(n>=3) { for(int i=0;i<m;i++) { int j=i%3; putchar('a'+j); } } else { if(m<=8) { printf("%s\n",temp[m]); continue; } printf("aaaa"); m-=4; int num=m/6; for(int i=1;i<=num;i++) printf("%s",ba); m-=num*6; for(int i=0;i<m;i++) putchar(ba[i]); } } putchar('\n'); } return 0; }