import java.util.Scanner; public class P1238 { public static int find(String[] arr) { int n = 1, max = 0; for (String s : arr) if (s.length() > n) n = s.length(); int[] count = new int[n + 1]; String[] sarr = new String[arr.length]; for (String s : arr) ++count[s.length()]; for (int i = 1; i < count.length; ++i) count[i] += count[i - 1]; for (int i = arr.length - 1; i >= 0; --i) sarr[--count[arr[i].length()]] = arr[i]; for (int i = 0; i < sarr[0].length(); ++i) { for (int j = i + (max == 0 ? 1 : max); j < sarr[0].length() + 1; ++j) { String ss = sarr[0].substring(i, j); char[] tmp = new char[ss.length()]; int k = tmp.length - 1; for (char c : ss.toCharArray()) tmp[k--] = c; String rs = new String(tmp); boolean find = true; for (k = 1; k < sarr.length; ++k) { if (! (sarr[k].indexOf(ss) > -1 || sarr[k].indexOf(rs) > -1)) { find = false; break; } } if (find) max = ss.length(); else break; } } return max; } public static void main(String[] args) { Scanner in = new Scanner(System.in); StringBuilder b = new StringBuilder(); while (in.hasNextLine()) { String l = in.nextLine(); int cn = Integer.parseInt(l); while (cn-- > 0) { if (in.hasNextLine()) { l = in.nextLine(); int sn = Integer.parseInt(l); String[] arr = new String[sn]; for (int i = 0; i < sn; ++i) { if (in.hasNextLine()) arr[i] = in.nextLine(); } b.append(find(arr)).append("\r\n"); } } } System.out.print(b.toString()); } }主要的思想很简单,先将字符串按长度从小到大排序,取最短的字符串的所有子串,进行判断,是否是其他的子串等。这里有两个小的优化:
- 每次取子串长度至少是上次计算得出的max
- 如果某个长度的子串,已经不满足条件,再长的就更无法满足了
算法比较简单,但是我测试做得不够充分,提交了5次才ac了。总结一点测试应该注意的,尽量选取比较独特的,有代表性的用例。