2018华工赛 E-Youhane Assembler(暴力水过)

最长公共前后缀查询问题
我们给出一个字符串的集合,在这个集合中有个字符串,编号为的字符串的长度为。我们给出个查询,每个查询是一个整数对,表示我们假定号串在左边,号串在右边,我们要查询的是最大的长度使号串的前缀与号串的后缀相等。

如我们有串:”ACGT”、”AACCGGTT”、“AAAA”,则查询(2,3)的结果为0,因为”AAAA”在右面欲与左面的”AACCGGTT”进行拼接,显然并没有公共的前后缀区域可以使两串拼接。而查询(3,2)的结果为2,因为此时“AAAA”放在了左面欲与右面的”AACCGGTT”拼接,这时有最长的公共区域”AA”。

题目链接:https://www.nowcoder.com/acm/contest/94/E

暴力,暴力,然后存了一下重复数据极限水过的,这题测试数据里应该有不少重复数据。

public class Main {
    public static void main(String[] args) {
        PrintWriter out = new PrintWriter(System.out);
        InputReader reader = new InputReader();
        int n = reader.nextInt();
        String[] seq = new String[n + 1];
        for (int i = 1; i <= n; i++) {
            seq[i] = reader.next();
        }
        int q = reader.nextInt();
        HashMap<String, Integer> map = new HashMap<>();
        while (q-- > 0) {
            int a = reader.nextInt();
            int b = reader.nextInt();
            String s = "";//用字符串来存查询key
            s += a;
            s += " ";//加个空格,不然wa,猜测是哈希冲突
            s += b;
            if (map.containsKey(s)) {
                out.println(map.get(s));
                continue;
            }
            int pre = KMP(seq[a].length(), seq[b].length(), seq[a], seq[b]);
            map.put(s, pre);
            out.println(pre);
        }
        out.close();
    }

    //虽然写着kmp但其实是暴力....一时没反应过来kmp怎么写就先暴力了,居然就a了
    public static int KMP(int n, int m, String s, String p) {
        int i = n - m;
        if (i < 0) {
            i = 0;
        }
        while (i < n) {
            if (s.substring(i, n).equals(p.substring(0, n - i))) {
                return n - i;
            }
            i++;
        }
        return 0;
    }

}

class InputReader {
//输入挂,略
}

什么?能不能不这么暴力?
附上一个很妙的代码。

public class Main {
    static int[] next = new int[300005];

    public static void main(String[] args) {
        // Scanner reader = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        InputReader reader = new InputReader();
        int n = reader.nextInt();
        String[] seq = new String[n + 1];
        for (int i = 1; i <= n; i++) {
            seq[i] = reader.next();
        }
        int q = reader.nextInt();
        StringBuilder check = new StringBuilder();
        while (q-- > 0) {
            int a = reader.nextInt();
            int b = reader.nextInt();
            check.append(seq[b] + "*" + seq[a]);
            int len = check.length();
            setPrefix(len, check.toString());
            out.println(next[len]);
            check.delete(0, len);
        }
        out.close();
    }

    public static void setPrefix(int m, String p) {
        int j = 0, k = -1;
        next[0] = -1;
        while (j < m) {
            if (k == -1 || p.charAt(j) == p.charAt(k)) {
                j++;
                k++;
                next[j] = k;
            } else
                k = next[k];
        }
    }

}

class InputReader {
//还是输入挂,略
}

打星号太骚了!!!!抄袭大佬的。
这里写图片描述

运行时间爆减,之前那个真的是极限水过的。

猜你喜欢

转载自blog.csdn.net/cymbals/article/details/79851827