普及练习场 深度优先搜索 单词接龙

来源:互联网 发布:ubuntu 启动服务命令 编辑:程序博客网 时间:2024/06/05 10:21

题意理解

这题目,如果裸写dfs的话,可能会比较烦,所以需要预处理一下。这个预处理还是很关键的,我昨天没有想到预处理,然后心态就很爆炸,什么都没有写出来。

另外,还有很重要的一点是,对于开始位置的处理。这个是在main方法中循环调用dfs,昨天也没有想清楚关于开头部分的处理,所以心态爆炸。

代码

import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class Main {    static int len = 0;    static int ans = 0;    private static int n;    static String[] ch;    static String hd; // head    static int[] cnt;    static List<Integer>[] v; // 记录每个字符串后面可以接的别的字符串的index    static List<Integer>[] w; // 记录每个字符串后面可以接的别的字符串的长度    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        n = scanner.nextInt();        ch = new String[n];        cnt = new int[n];        for (int i = 0; i < n; i++) {            cnt[i] = 0;        }        v = new ArrayList[n];        for (int i = 0; i < n; i++) {            v[i] = new ArrayList<>();        }        w = new ArrayList[n];        for (int i = 0; i < n; i++) {            w[i] = new ArrayList<>();        }        for (int i = 0; i < n; i++) {            ch[i] = scanner.next();        }        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                int t = solve(i, j);                if (t != 0) {                    v[i].add(j);                    w[i].add(ch[j].length() - t);                }            }        }        /***********************上面是预处理**************************/        hd = scanner.next();        scanner.close();        for (int i = 0; i < n; i++) {            if (ch[i].charAt(0) == hd.charAt(0)) {                cnt[i]++;                dfs(i, ch[i].length());                cnt[i]--;            }        }        System.out.println(ans);    }    // u表示当前接龙的字符串最后来自的字符串的编号    static void dfs(int u, int len) {        if (len > ans) {            ans = len;        }        for (int i = 0; i < v[u].size(); i++) {            if (cnt[v[u].get(i)] < 2) {                cnt[v[u].get(i)]++;                int x = v[u].get(i);                int y = w[u].get(i);                dfs(x, len + y);                cnt[v[u].get(i)]--;            }        }    }    // 编号为x的字符串,后面能否让编号为y结尾的字符串接在后面,如果可以,则返回最长可以变长多少    private static int solve(int x, int y) {        int l1 = ch[x].length();        int l2 = ch[y].length();        for(int i = 1; i < Math.min(l1, l2); i++) {            if(ch[x].endsWith(ch[y].substring(0, i))) {                // 这是要保证不会出现一个单词包含了另一个单词的情况。我觉得吧,其实不写好像也没有什么关系啊。。。然后我就注释了爆交了一发,结果过了                // 原理其实很简单,如果一个单词包含了另一个单词,其实也就是搜索的时候多搜索一次,而对于整个接龙没有影响//              if(i == Math.min(l1, l2)) {//                  if(ch[x].charAt(l1 - i + 1) != ch[y].charAt(i - 1)) {//                      return i;//                  }//              } else {//                  return i;//              }                return i;            }        }        return 0;    }}

欢迎加入“不会算法一群菜鸟”,群号是⑥⑥①⑨②2025,这是我设置的一道很低的门槛用来阻止广告的。入群的验证暗号是:我爱编译原理

原创粉丝点击