# JudgeGirl #32 ## Longest Double Palindrome For example `1 3 5 3 1` and `1 2 2 1` are both palindromes. To the extreme case `1` is also a palindrome. We also define a double palindrome as the concatenation of two palindromes. For example `1 3 5 3 1 1 2 2 1` is a double palindrome. To the extreme case `1 3 5 3 1 1` is also a double palindromes ## Keys ### 1. Define isPallind() For each number in between, check every corresponding number on the opposite side. Until the corresponding num is self or behind. Return 0 if does not match ```c int isPalind(int h, int t) { // h = head, t = tail if (h == t) return 1; // extreme case (single number) int c = t - h - 1; // count of numbers in between for (int i = 1; i < c; i++) { if (t - i < h + i) break; // is behind if (a[h+i] != a[t-i]) return 0; // not match } return 1; } ``` ### 2. Remember every longest palindrome we've seen We don't keep track of every palin because that's too many. Keep track of every longest one to save some space. Save them into 2 arrays so that each pallin's `(start, end)` is `(heads[i], tail[i])`. ```c int heads[128], tails[128], count = 0; for (int i = 0; i < c; i++) { for (int j = c - 1; j >= i; j--) { if (a[i] == a[j] && isPallind(i, j)) { heads[count] = i; tails[count] = j; count++; break; } } } ``` ### 3. Determine the longest palindrome Loop through every palin `i` we've seen, and for each of them loop through every palin `j` from back of the array, check if the head of `j` is the tail + 1 of `i` (next to each other). Update ans if length of current one is >= ans. If `i` is the last one and there's no next one, `i` will be `i - 1` and `j` will be the last one. ```c int max = 0, ansi = 0, ansj = 0; for (int i = 0; i < count - 1; i++) { int nexttail = tails[count - 1]; // default j for (int j = i + 1; j < count; j++) { // next to each other if (heads[j] == tails[i] + 1) nexttail = tails[j]; // } int thishead = heads[i]; // when i is last and no next one if (nexttail == tails[i]) thishead = heads[i - 1]; // update ans if (nexttail - thishead >= max) { max = nexttail - thishead; ansi = thishead; ansj = nexttail; } } ``` ## Code ```c #include <stdio.h> int a[128]; int isPalind(int h, int t) { if (h == t) return 1; int c = t - h - 1; // count of numbers in between for (int i = 1; i < c; i++) { if (t - i < h + i) break; if (a[h+i] != a[t-i]) return 0; } return 1; } int main() { int c = 0; while (scanf("%d", &a[c]) != EOF) c++; int heads[128], tails[128], count = 0; for (int i = 0; i < c; i++) { for (int j = c - 1; j >= i; j--) { if (a[i] == a[j] && isPalind(i, j)) { heads[count] = i; tails[count] = j; count++; break; } } } int max = 0, ansi = 0, ansj = 0; for (int i = 0; i < count - 1; i++) { int nexttail = tails[count - 1]; for (int j = i + 1; j < count; j++) { if (heads[j] == tails[i] + 1) nexttail = tails[j]; } int thishead = heads[i]; if (nexttail == tails[i]) thishead = heads[i - 1]; if (nexttail - thishead >= max) { max = nexttail - thishead; ansi = thishead; ansj = nexttail; } } for (int i = ansi; i <= ansj; i++) printf("%d%c", a[i], " \n"[i==ansj]); return 0; } ```