8.27网易笔试题




我共通过两题,最后一题一直超时。

第一题,贴墙纸。
思路:把需要的所有墙纸贴好,然后取出中间的m*m的子矩阵就可以了
代码如下:
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        while (T-- > 0) {
            int n = in.nextInt();
            int m = in.nextInt();

            char[][] a = new char[n][];
            for (int i = 0; i < n; i++) a[i] = in.next().toCharArray();
            getCenterMatrix(n, m, a);
        }

    }

   

    private static void getCenterMatrix(int n, int m, char[][] a) {
        int width = 1 + ((m - n - 1) / (2 * n) + 1) * 2;
        //System.out.println("width = " + width);
        char[][] c = new char[width*n][width*n];
        for (int i = 0; i < c.length; i += n) {
            for (int j = 0; j < c.length; j += n) {
                for (int k = 0; k < n; k++) {
                    for (int h = 0; h < n; h++) {
                        c[i+k][j+h] = a[k][h];
                    }
                }
            }
        }

        int st = (width * n - m) / 2;
        for (int i = st; i < st+m; i++) {
            for (int j = st; j < st+m; j++) {
                System.out.print(c[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }
}

第二题,求矩阵覆盖的面积。难点在于有多个矩阵覆盖了同一块区域,但是这块区域的面积只能被计算一次。如果暴力去做可能会超时,于是观察题目数据量,矩形的坐标范围在[0,1000]之间,同时矩阵的数量为[1, 500],所有可以考虑枚举Y轴,然后把包含这个Y轴的所有矩阵在这条Y轴上的面积都计算一遍!为了计算的快速,需要先按照x0坐标排序,问题就转化为了如下问题:
给你一堆线段, [1,3], [5, 7],...,请你算出线段所覆盖的最大长度!
这样就能算出每一个Y坐标覆盖的面积,然后把0-1000的面积加起来就是总的面积了。
注意:边缘不能重复计算,比如矩阵[0,0,1,1]的面积为1,而不是4,也就是说y为0时不可以和y为1时同时计算。我在代码中没有考虑矩阵的下边缘。
if (i > y0 && i <= y1) // 不考虑下边缘
AC代码如下:
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        int x0, y0, x1, y1;
        while (T-- > 0) {
            int n = in.nextInt();
            ArrayList<int[]> recs = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                x0 = in.nextInt();
                y0 = in.nextInt();
                x1 = in.nextInt();
                y1 = in.nextInt();
                recs.add(new int[]{x0, y0, x1, y1});
            }

            // 按照x0排序
            recs.sort(Comparator.comparingInt(o -> o[0]));

            // 找出有效矩阵
            boolean[] ok = new boolean[n];
            for (int i = 0; i < n; i++) {
                if (!ok[i]) {
                    for (int j = i + 1; j < n; j++) {
                        if (crossed(recs.get(i), recs.get(j))) {
                            ok[i] = ok[j] = true;
                        }
                    }
                }
            }

            //System.out.println(Arrays.toString(ok));

            int area = 0;
            for (int i = 0; i <= 1000; i++) {
                int len = 0, st = -1, end = -1;
                for (int j = 0; j < n; j++) {
                    if (!ok[j]) continue;
                    int[] t = recs.get(j);
                    x0 = t[0];
                    y0 = t[1];
                    x1 = t[2];
                    y1 = t[3];

                    //if (y1 == i) continue;
                    if (i > y0 && i <= y1) { // 不考虑下边缘
                        if (x0 > end) {
                            len += x1 - x0;
                            end = x1;
                        } else if (x1 > end) {
                            len += x1 - end;
                            end = x1;
                        }
                    }
                }
                area += len;
            }

            System.out.println(area);

        }

    }

    private static boolean crossed(int[] r1, int[] r2) {
        // x0 >= x1
        if (r1[0] >= r2[2] || r2[0] >= r1[2]) return false;
        // y0 >= y1
        if (r1[1] >= r2[3] || r2[1] >= r1[3]) return false;
        return true;
    }
}

第三题,手机图案的种类数量。
思路:枚举所有可能的边,但是超时。。。有AC大佬给个思路吗?



#网易互娱##算法题##网易##笔试##投票##秋招#
全部评论
第一道可以把墙纸的坐标映射到花纹矩阵中,保证数据在矩阵范围内就行; 第二题我记得题干有“每个矩形最多只与一个矩形相交”,这样直接标记一下遍历即可; 第三题摸了。
1 回复 分享
发布于 2022-08-28 10:40 浙江
第三题我的思路是dfs,给所有两点边编码(共有28条,记录在代码中的edges),其余8条三点边,分开存储为2条边(代码中的dup),然后就是常规的dfs,用一个map记录边出现的次数,如果发现下一条边是三点边,则用map把该三点边对应的两条两点边的数量加一,如果发现下一条边经过2个点,则直接将这个两点边的数量加一,但是我们只有在边的数量刚好加到1的时候或者刚好减到0的时候才去更新这条边的状态。
点赞 回复 分享
发布于 2022-08-27 23:40 山东
第一题竟然可以先画全部的再取子图!没想到啊!我是把整个图包括不完整的边分为了9个部分挨个求出来再拼到一起🤣🤣楼主的思路简便多了
点赞 回复 分享
发布于 2022-08-27 23:40 广东
看到有大佬投了ak,能不能分享下第三题的思路或者代码
点赞 回复 分享
发布于 2022-08-27 22:46 广东

相关推荐

03-19 10:07
已编辑
广东药科大学 golang
Yki_:你倒是进一个面啊
点赞 评论 收藏
分享
评论
1
9
分享

创作者周榜

更多
牛客网
牛客企业服务