2020暑期实习后台开发字节跳动笔试

1

输入:第一行为操作总数Q,之后有Q行。每行一个操作。
操作1,将字符串加在原字符串末尾。
操作2,给定长度,从字符串末尾删除。
操作3,查询现在字符串中第k个字符。
操作4,回滚一次操作(只回滚增删操作)。
难度:easy
耗时:10min

public class Main {
    static StringBuilder sb = new StringBuilder();
    static Stack<String> st = new Stack();
    
    private static void add(String s) {
        st.push(sb.toString());
        sb.append(s);
    }
    
    private static char search(int pos) {
        return sb.charAt(pos-1);
    }
    
    private static void delete(int len) {
        st.push(sb.toString());
        sb.setLength(sb.length() - len);
    }
    
    private static void rollback() {
        sb = new StringBuilder(st.pop());
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int Q = sc.nextInt();
        sc.nextLine();
        for (int j = 0; j < Q; j++) {
            String[] arr = sc.nextLine().split("\\s+");
            if (arr[0].equals("1"))
                add(arr[1]);
            else if (arr[0].equals("2"))
                delete(Integer.parseInt(arr[1]));
            else if (arr[0].equals("3")) {
                char c = search(Integer.parseInt(arr[1]));
                System.out.println(c);
            } else
                rollback();
        }
    }
}

2

输入:第一行为需要翻译的文本M。len(M) <= 50000.
第二行为字典中单词数n。2 <= n <= 50000.
每一个单词长度不超过20。
之后有n行,每一行代表一个单词。
返回总共有多少种翻译文本的方式。
返回的结果需要%835672545。
样例:

abcba
5
a
ab
ba
bc
cb

// 输出2
ab | cb | a
a | bc | ba

难度:medium
耗时:50min
一开始没有降维,MLE。

public class Main {
    static final int kMod = 835672545;
    private static int search(HashSet<String> dict, String s) {
        int n = s.length();
        int[][] dp = new int[n+1][n+1];
        for (int i = 1; i <= n; i++)
            for (int j = i; j <= n; j++) {
                String tmp = s.substring(i-1, j);
                if (dict.contains(tmp))
                    dp[i][j] = 1;
            }
        for (int len = 1; len <= n; len++) {
            for (int i = 1; i+len-1 <= n; i++) {
                int j = i + len - 1;
                for (int k = i; k < j; k++) {
                    String s2 = s.substring(k, j);
                    if (dp[i][k] > 0 && dict.contains(s2)) {
                        dp[i][j] = (dp[i][j] + dp[i][k]) % kMod; 
                    }
                }
            }
        }
//        System.out.println(dp[1][1]); //a
//        System.out.println(dp[1][2]); // ab
//        System.out.println(dp[1][3]); // a | bc
//        System.out.println(dp[1][4]); // ab | cb
        return dp[1][n];
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String target = sc.nextLine();
        int Q = sc.nextInt();
        sc.nextLine();
        HashSet<String> dict = new HashSet();
        for (int j = 0; j < Q; j++) {
            dict.add(sc.nextLine());
        }
        System.out.println(search(dict, target));
    }

}

第二次,没有用Math.max优化长度,TLE。而且显示test case通过率为0,特别慌。
第三次终于AC。

public class Main {
    static final int kMod = 835672545;
    private static int search(HashSet<String> dict, String s) {
        int n = s.length();
        int[] dp = new int[n+1];
        dp[0] = 1;
        for (int r = 1; r <= n; r++) {
            for (int l = Math.max(1, r-20); l <= r; l++) {
                String tmp = s.substring(l-1, r);
                if (dp[l-1] > 0 && dict.contains(tmp))
                    dp[r] = (dp[r] + dp[l-1]) % kMod; 
            }
        }

        return dp[n];
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String target = sc.nextLine();
        int Q = sc.nextInt();
        sc.nextLine();
        HashSet<String> dict = new HashSet();
        for (int j = 0; j < Q; j++) {
            dict.add(sc.nextLine());
        }
        System.out.println(search(dict, target));
    }
}

3

输入:第一行两个整形,m表示天数,n表示袜子数量(只)。
第二行是每只袜子的颜色(用整形表示)。
之后有m行,每一天穿两只固定序号的袜子。但是必须保证两只袜子颜色一样。如果不一样,需要涂改袜子的颜色使这两只袜子的颜色能够匹配。代价为1。
返回最小代价。
难度:medium - hard
耗时:10min
应该是个dp问题。但是我连暴力解都没写出来。下面是个错误解法。

public class Main {
    static int[] color;
    static int[] color2;
    static int[][] comb;
    static int m;// number of days
    static int n;// number of socks
    private static int paint() {
        // dp[i][j][k] := min number of painting
        // in day i, painting j-th sock to color k
//        int[][][] dp = new int[m+1][n][n];
//        dp[0] = color.clone();
        int cnt = 0;
        for (int i = 0; i < m; i++) {
            int sock1 = comb[i][0];
            int sock2 = comb[i][1];
            boolean same1 = true;
            boolean same2 = true;
            if (color[sock1] != color[sock2]) {
                color[sock1] = color[sock2];
                same1 = false;
            }
            if (color2[sock1] != color2[sock2]) {
                color2[sock2] = color2[sock1];
                same2 = false;
            }
            if (!same1 && !same2)
                cnt++;
        }
        return cnt;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();  
        m = sc.nextInt();  
        color = new int[n+1];
        comb = new int[m][2];
        for (int i = 1; i <= n; i++) {
            int c = sc.nextInt();
            color[i] = c;
        }
        color2 = color.clone();
        sc.nextLine();
        for (int j = 0; j < m; j++) {
            String[] arr = sc.nextLine().split("\\s");
            comb[j][0] = Integer.parseInt(arr[0]);
            comb[j][1] = Integer.parseInt(arr[1]);
        }
        System.out.println(paint());
    }
}

4

对给定字符串有两种操作。
操作1,修改第k个字符为新字符c。
操作2,查询给定范围内不同字符的个数。
难度:hard
耗时:10min
没写出来,只写了一个暴力解,60%测试用例超时。
我估计使用Trie。

public class Main {
    static StringBuilder sb = null;

    private static int query(int l, int r) {
        HashSet<Character> cnt = new HashSet();
        for (int i = l-1; i < r; i++) {
            cnt.add(sb.charAt(i));
        }
        return cnt.size();
    }

    private static void update(int pos, String s) {
        sb.setCharAt(pos-1, s.charAt(0));
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String target = sc.nextLine();
        sb = new StringBuilder(target);
        int Q = sc.nextInt();
        sc.nextLine();
        HashSet<String> dict = new HashSet();
        for (int j = 0; j < Q; j++) {
            String[] arr = sc.nextLine().split("\\s");
            if (arr[0].equals("2")) { // query
                System.out.println(query(Integer.parseInt(arr[1]), Integer.parseInt(arr[2])));
            } else {
                update(Integer.parseInt(arr[1]), arr[2]);
            }
        }
    }
}

做完心态是崩溃的。

猜你喜欢

转载自blog.csdn.net/qq_40136685/article/details/106051133