洛谷P1019
来一道简单的递归
题目如下:
题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast 和 astonish,如果接成一条龙则变为 beastonish,另外相邻的两部分不能存在包含关系,例如 at 和 atide 间不能相连。
输入格式
输入的第一行为一个单独的整数 nn 表示单词数,以下 nn 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
输出格式
只需输出以此字母开头的最长的“龙”的长度。
输入输出样例
输入 #1
5 at touch cheat choose tact a
输出 #1
23
说明/提示
样例解释:连成的“龙”为 atoucheatactactouchoose。
n \le 20n≤20
分析一下:
1. 单词不能被包含。
2. 单词最多能使用两次。
3. n最大为20,可以考虑递归深搜
package pro.luogu; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.StringTokenizer; public class P1019 { private static int ans, n; private static int[] visited; private static String[] strs; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); n = Integer.parseInt(st.nextToken());//单词数量 strs = new String[n]; //单词数组 visited = new int[n];//使用次数数组 for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine()); strs[i] = st.nextToken(); } st = new StringTokenizer(br.readLine()); String start = st.nextToken();// 开始拼接的单个字符 ans = 0;//最开始的长度为0 dfs(start); System.out.println(ans); // System.out.println(checkDuplicate("touch","uchu")); } //简单递归 private static void dfs(String end) { for (int i = 0; i < n; i++) { if(visited[i] < 2) { // 使用次数不到两次,就可以使用 //判断当前第i个单词是否能够使用,不能使用返回-1,可以使用返回第i个单词的重叠部分的索引 int duplicate = checkDuplicate(end, strs[i]); if(duplicate != -1) { visited[i]++;//可以使用,使用次数加一 if((end+strs[i].substring(duplicate+1)).length() > ans) {//拼接的新单词长度进行对比 //更新最大拼接的长度 ans = (end+strs[i].substring(duplicate+1)).length(); } dfs(end+strs[i].substring(duplicate+1));//可以成功拼接继续递归 visited[i]--;//回溯的时候需要将使用次数减一。以防下一波循环又可以用 } } } } // 判断单词重复的部分 private static int checkDuplicate(String start, String str) { // 获取较短的字符串长度 int len = start.length() > str.length() ? str.length() : start.length(); for (int i = 0; i < len; i++) { //如果str的前面截取和start最后的截取一致就进入 if(str.substring(0, i+1).equals(start.substring(start.length()-1-i))) { //如果是单个字符,不用判断是否包含,其他字符需要判断是否全部被使用。 if(i != len-1 || start.length() == 1) { return i; //返回索引 } } } return -1;//返回失败索引 } }

浙公网安备 33010602011771号