前言:java
药丸啊药丸啊真的药丸啊,几天时间没作题,昨天作了一道单词接龙题,作了一整个晚上啊,大几个小时。原本想昨天十一点多的时候,也就是好不容易AC了以后就写题解的,但是AC了以后反而身心俱疲,感受本身蒟蒻,心态收到了冲击。数组
今天上完课写完做业后,仍是心有余悸... 再好好地回顾一下,写一篇题解吧。3d
分析:code
这道题的tag是搜索,可是其实还有字符串处理混杂在里面。blog
首先,理解题意就是一个坎,若是不是写到实在思惟混乱了,从新研究了一些样例数据,我可能就一直在错误的理解下挣扎了。仔细去看样例给出的五个单词at touch cheat choose tact, 最终以 a开头的最长的龙是atoucheatactactouchoose。字符串
要注意什么呢,题意要求,在两个单词相连时,其重合部分合为一个部分,也就是说,只有把单词的最小重合部分合并,才能保证最大,而且,要连就要整个单词连上去,不能截取。那么所受到的限制就仅仅是末尾最后一次接上的串了。必定要理清这个思路,不然会绕晕。字符串处理
另一个注意点时,每一个单词最多用两次,那就用int数组去计数,不要用boolean了。string
最后要特别注意的是,题目指出,相邻的部分不能存在包含关系,可是!若是是自身和自身链接,是不属于在包含关系里的,也就是说,容许自身和自身进行链接!it
还有其余的一些边边角角的就都写在注释里吧。class
实现:
import java.util.Scanner; public class Main { static int n = 0, result = 0; static String[] word; // 记录字符串 static char first; // 记录开头的字母 static int visit[]; // 记录单词出现的次数 static String link; // 记录链接串 // dfs搜索 static void dfs(String str) { String temp = str; if (result <= str.length()) { result = str.length(); } for (int i = 0; i < word.length; i++) { if (visit[i] < 2 && connect(str, word[i]) && check(str, word[i]) == false) { visit[i]++; dfs(link); str = temp; // 必定要回溯!不要改变str! visit[i]--; } } } // 检查是否为最小重合部分 static boolean connect(String a, String b) { char a1[] = a.toCharArray(); char b1[] = b.toCharArray(); for (int i = 0; i < Math.min(a.length(), b.length()); i++) { // 若是a1末尾的和a2开头的相等 if (a1[a1.length - 1] == b1[i]) { // 两个串分别往前推着检查 for (int j = a1.length - 1, k = i; j >= 0 && k >= 0; j--, k--) { if (a1[j] != b1[k]) { return false; } // 若是检查直到b1的第一位,都相等,则找到了重合部分 if (k == 0) { b = b.substring(i + 1);// 取出这个重合部分,留下后面的字符串 link = a + b;// 造成链接串 return true; } } } } return false; } // 检查是否有包含关系 public static boolean check(String a, String b) { // 相同不算在包含的状况下 if (a.equals(b)) { return false; } // 没有包含关系: for (int i = 0; i < Math.min(a.length(), b.length()); i++) { if (a.charAt(i) != b.charAt(i)) { return false; } } return true; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); word = new String[n]; for (int i = 0; i < n; i++) { word[i] = sc.next(); } first = sc.next().charAt(0); visit = new int[n]; sc.close(); for (int i = 0; i < word.length; i++) { if (word[i].charAt(0) == first) { dfs(word[i]); } } System.out.println(result); } }