Java 笔试【xc-0907】

面试要线下参加,是为了检验我的诚心吗?

题目的内容参考:https://www.nowcoder.com/discuss/529638802495721472

T1:相邻的数不能是合数

不知道咋做,用的 dfs。

public static void main11(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int ans = 0;
            int[] arr = new int[n];
            boolean[ ] visited = new boolean[n];
            ans = dfs(0, visited, arr);
            System.out.println(ans);

        }
    }

    private static int dfs(int idx, boolean[] visited, int[] arr) {
        if (idx == visited.length) return 1;
        int ans = 0;
        for (int i = 0; i < visited.length; i++) {
            if (visited[i]) continue;
            if (idx > 0 && isP(arr[idx - 1] + 1 + i + 1)) continue;
            visited[i] = true;
            arr[idx] = i;
            ans += dfs(idx + 1, visited, arr);
            arr[idx] = 0;
            visited[i] = false;
        }
        return ans;
    }

    private static boolean isP(int num) {
        switch (num) {
            case 2:
            case 4:
            case 6:
            case 8:
            case 9:
            case 10:
            case 12:
            case 14:
            case 15:
            case 16:
            case 18:
            case 20:
                return false;
            default:
                return true;
        }
    }

T2:三角形

给出n*m的字符矩阵,求三点分别为y o u的直角三角形个数。只过了10%。

思路:记录 y 和 o 的位置,for 循环,获取合格的 u 的位置。时间复杂度 (n*m) * (n*m)。

这个思路错误的地方在于,我们其实只需要记录每行每列的 y 和 o,不需要记录每个 y 和 o。

public static void main22(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int row = in.nextInt();
            int col = in.nextInt();
            List<int[]> ys = new ArrayList<>();
            List<int[]> os = new ArrayList<>();

            Map<Integer, Integer> xCnts = new HashMap<>();
            Map<Integer, Integer> yCnts = new HashMap<>();
//            Map<Integer, Integer> cnts = new HashMap<>();
            Set<Integer> set = new HashSet<>();
            for (int i = 0; i < row; i++) {
                String str = in.next();
                char[] cs = str.toCharArray();
                for (int j = 0; j < col; j++) {
                    char c = cs[j];
                    switch (c) {
                        case 'y': ys.add(new int[]{i, j}); break;
                        case 'o': os.add(new int[]{i, j}); break;
                        case 'u':
                            add(xCnts, i);
                            add(yCnts, j);
                            set.add(i * col + j);
                            break;
                        default: break;
                    }
                }
            }
            int ans = 0;
            for (int[] y: ys) {
                int x1 = y[0];
                int y1 = y[1];
                for (int[] o: os) {
                    int x2 = o[0];
                    int y2 = o[1];

                    if (x1 == x2) {
                        // 已经有水平线
                        ans += yCnts.getOrDefault(y1, 0) + yCnts.getOrDefault(y2, 0);
                    } else if (y1 == y2) {
                        // 已经有竖直线
                        ans += xCnts.getOrDefault(x1, 0) + xCnts.getOrDefault(x2, 0);
                    } else {
                        // {x1, y2}
                        // {x2, y1}
                        ans += set.contains(x1 * col + y2) ? 1 : 0;
                        ans += set.contains(x2 * col + y1) ? 1 : 0;
                    }
                }
            }
            System.out.println(ans);
        }
    }

    public static void add(Map<Integer, Integer> map, int key) {
        if (map.containsKey(key)) {
            map.put(key, map.get(key) + 1);
        } else {
            map.put(key, 1);
        }
    }

T3:数组操作次数

给出n个整数,每次可以选两个分别+1-1,求使得n个数都位于[l, r]的最少操作次数,不存在则输出-1枚举每个数,对小于左边界的数用一个变量记录差值,大于有边界的变量用另一个数记录差值,最后输出两个变量中大的那个。

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int t = in.nextInt();

            for (int i = 0; i < t; i++) {
                int n = in.nextInt();
                int l = in.nextInt();
                int r = in.nextInt();
                int[] arr = new int[n];
                long sum = 0L;
                List<Integer> nums = new ArrayList<>();
                long lack = 0;
                long remain = 0;
                for (int j = 0; j < n; j++) {
                    int num = in.nextInt();
                    arr[j] = num;
                    sum += num;
                    if (num < l || num > r) nums.add(num);
                    if (num < l) lack += l - num;
                    if (num > r) remain += num - r;
                }
                if (sum < (long)l * n || sum > (long)r * n) {
                    System.out.println(-1);
                    continue;
                }
                System.out.println(Math.max(lack, remain));
            }
        }
    }

T4:好串

给一个0和1组成的字符串,求子串中有多少“好串”。对“好串”的定义是:所有的前缀子串中,0的数量全部严格大于1的数量。

思路:主要想法是用前缀和+单调栈。前缀和在遍历到 1 则加 1,遇到 0 则减 1。对于每一个左端点来说,合法的右端点是这个区间的前缀和值都大于等于左端点的前缀和值。因此考虑记录每一个位置的前缀和值,查询时用单调栈找到左端点的第一个小于左端点的前缀和值的位置,减一下就得到对应的区间对答案的贡献。时间复杂度O(nlogn)。

参考:https://www.nowcoder.com/feed/main/detail/17274cfeb3c143cdb4dc6e2bba0cd5df?sourceSSR=search

Java 后端笔经 文章被收录于专栏

Java 后端笔试经验

全部评论

相关推荐

点赞 评论 收藏
转发
3 1 评论
分享
牛客网
牛客企业服务