题目大意:用m个字母组成一个长度为N的字符串,使得最长的回文子串 的长度最小。 并且要求字典序最小。
思路:分类模拟。
当M为1 的时候就直接输出N个A
当M大于2的时候就循环ABC
当M等于2的时候
先枚举出当N<9 的情况,因为此时可以用最长串长度为 3 的基础上得到。
而当N>9的时候。
其实就是 aababb 为循环节的一个循环。但是此时是建立在最长串为4的基础上得到
但是有另外的情况就是
m==2 n%6<=4的时候最后面就不是循环循环节了。
例如:
m=2 n=10
aababbaaaa.
而不是
aababbaaba.
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <vector> #include <map> #include <set> using namespace std; #ifdef WIN typedef __int64 LL; #define iform "%I64d" #define oform "%I64d " #else typedef long long LL; #define iform "%lld" #define oform "%lld " #endif const double eps = 10e-9; #define SI(a) scanf("%d", &(a)) #define SDI(a, b) scanf("%d%d", &(a), &(b)) #define SUI(a) scanf("%ud", &(a)) #define S64I(a) scanf(iform, &(a)) #define SS(a) scanf("%s", (a)) #define SC(a) scanf("%c", &(a)) #define PI(a) printf("%d ", a) #define P64I(a) printf(oform, a) #define Max(a, b) (a > b ? a : b) #define Min(a, b) (a < b ? a : b) #define MSET(a, b) (memset(a, b, sizeof(a))) #define Mid(L, R) (L + (R - L)/2) #define ABS(a) (a > 0 ? a : -a) #define REP(i, n) for(int i=0; i < (n); i++) #define FOR(i, a, n) for(int i=(a); i <= (n); i++) typedef unsigned int UINT; const char tab[8][20] = { "a", "ab", "aab", "aabb", "aaaba", "aaabab", "aaababb", "aaababbb"}; int main() { int T; SI(T); FOR(kase, 1, T) { int m, n; SDI(m, n); printf("Case #%d: ", kase); if(m>2) { //int tn = n - m + 3; int a = n / 3; int b = n % 3; REP(i, a) printf("abc"); REP(i, b) printf("%c", 'a'+i); //REP(i, m-3) printf("%c", 'd'+i); printf(" "); } else if(m == 1) { REP(i, n) putchar('a'); printf(" "); } else { if(n < 9) { printf("%s ", tab[n-1]); } else { char t[] = "babbaa"; printf("aaaa"); int a = (n-4) / 6; int b = (n-4) % 6; REP(i, a) printf("babbaa"); if(b <= 2) REP(i, b) putchar('a'); else REP(i, b) putchar(t[i]); printf(" "); } } } return 0; }