#include #include int lengths[2048][2048], arrows[2048][2048]; char s[4096]; int length; #define S(n) s[n-1] #define R(n) s[(length-1)-(n-1)] #define LEFT 0 #define UP 1 #define DIAG 2 int lcs(int n, char result[4096]) { int slength = n, rlength = length - n; { int i, j; for (i = 1; i <= slength; i++) { for (j = 1; j <= rlength; j++) { if (lengths[i-1][j] > lengths[i][j-1]) { lengths[i][j] = lengths[i-1][j]; arrows[i][j] = LEFT; } else { lengths[i][j] = lengths[i][j-1]; arrows[i][j] = UP; } if (S(i) == R(j)) { if (lengths[i-1][j-1] + 1 >= lengths[i][j]) { lengths[i][j] = lengths[i-1][j-1] + 1; arrows[i][j] = DIAG; } } } } } { char tmp[4096]; int n_tmp = 0; int n_result = 0; int i = slength, j = rlength; if (lengths[slength][rlength] * 2 < lengths[slength-1][rlength] * 2 + 1) { i--; } while (lengths[i][j] > 0) { if (arrows[i][j] == DIAG) { tmp[n_tmp] = S(i); n_tmp++; i--; j--; } else if (arrows[i][j] == UP) { j--; } else { i--; } } tmp[n_tmp] = '\0'; for (i = n_tmp - 1, j = 0; i >= 0; i--, j++) { result[j] = tmp[i]; n_result++; } if (lengths[slength][rlength] * 2 < lengths[slength-1][rlength] * 2 + 1) { result[j] = s[n-1]; j++; n_result++; } result[j] = '\0'; return n_result + n_tmp; } } int main() { { int i, j; for (i = 0; i < 2048; i++) { lengths[i][0] = 0; } for (j = 0; j < 2048; j++) { lengths[0][j] = 0; } } while (1) { int i, j, max_result_length = 0, result_length = 0; char result[4096], rresult[4096], final_result[4096]; if (NULL == gets(s)) { break; } length = strlen(s); for (i = 1; i <= length; i++) { if (max_result_length < (result_length = lcs(i, result))) { max_result_length = result_length; strcpy(final_result, result); } } for (i = (max_result_length>>1)-1, j = 0; i >= 0; i--, j++) { rresult[j] = final_result[i]; } rresult[j] = '\0'; strcat(final_result, rresult); puts(final_result); } return 0; }