首页 > 其他分享 >2024年美团3.9笔试

2024年美团3.9笔试

时间:2024-03-10 10:11:05浏览次数:18  
标签:node Node Scanner int 美团 2024 new public 3.9

题目详情可以参照笔试题目,题解是本人根据网上提供的思路做的,可能会存在问题,仅供参考。

完美矩阵

小美拿到了一个n*n的矩阵,其中每个元素是 0 或者 1。小美认为一个矩形区域是完美的,当且仅当该区域内 0 的数量恰好等于 1 的数量。现在,小美希望你回答有多少个i*i的完美矩形区域。

关键词:二维前缀和

这题一开始的时候就想着使用1就加一,然后0就减一,最后判断是否为零的方法来判断是否是完美矩阵。但是这就就很复杂了。看别人说是二维前缀和就想到可以统计dp[i][j]是从左上角到ij位置的一的个数,然后判断是否是完美矩阵只需判断1的个数是否是当前矩阵元素个数的一半。读数据的时候当前位置的一的个数等于上方加左边再减去重复部分的1的个数。然后同理也可以指定指定子矩阵的1的个数。说实话这题不算特别难,但是一开始思路错了就没办法了,想不到这个知识点。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[][] nums = new int[n+1][n+1];
        String str;
        int temp,ans,all;
        //计算前缀和
        for(int i=0;i<n;i++){
            str = in.next();
            for(int j=0;j<n;j++){
                nums[i+1][j+1]=nums[i][j+1]+nums[i+1][j]+(str.charAt(j)-'0')-nums[i][j];
            }
        }

        for(int k=1;k<=n;k++){
            if(k%2!=0){
                System.out.println("0");
                continue;
            }
            ans = 0;
            all = k*k/2;
            for(int i=0;i+k<=n;i++){
                for(int j=0;j+k<=n;j++){
                    temp = nums[i+k][j+k]-nums[i+k][j]-nums[i][j+k]+nums[i][j];
                    if(temp==all) ans++;
                }
            }
            System.out.println(ans);
        }
    }   
}

最多的删除情况

小美拿到了一个大小为n的数组,她希望删除一个区间后,使得剩余所有元素的乘积末尾至少有k个 0。小美想知道,一共有多少种不同的删除方案?

关键词:数学、前缀和、滑动窗口

这题我只想到了使用前缀和来解决,因此会遇到乘法太大导致溢出的问题,当时还打算使用BigDecimal来解决,原来是自己想的简单了。这题除了前缀和,还考了数学问题,实际上能够得到10的倍数只与2和5的个数相关,其他因子对这个不产生影响。因此我们只需对数组中每个数进行分解,看里面包含多少个2和5,然后用前缀和的方式记录。然后就使用滑动窗口来寻找可以删除的区间。判断条件是这个剩下的区间的2和5的最小值与k进行比较,因为一个2和一个5相乘就是10,那么2和5的最小值就是末尾为零的个数。

import java.util.*;

public class MaxCase {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        long[] pre2 = new long[n+1];
        long[] pre5 = new long[n+1];
        int cnt2,cnt5,temp;

        for(int i=0;i<n;i++){
            temp = in.nextInt();
            cnt2=0;
            cnt5=0;
            for(int x=temp;x%2==0;x/=2) cnt2++;
            for(int x=temp;x%5==0;x/=5) cnt5++;
            pre2[i+1] = pre2[i] + cnt2;
            pre5[i+1] = pre5[i] + cnt5;
        }

        long res = 0;
        for(int i=0,j=0;i<n;i++){
            while(j<n){
                long remain2 = pre2[n] - pre2[j+1] + pre2[i];
                long remain5 = pre5[n] - pre5[j+1] + pre5[i];
                if(Math.min(remain2,remain5)<k) break;
                j++;
            }
            res += Math.max(j-i, 05);
        }

        System.out.println(res);
    }
}

朋友关系

关键词:并查集、逆序、栈、类、方法重写、集合

这题考到我的智商盲点的,我们需要维护一个并查集来记录朋友关系,这题难点就在于后期会存在遗忘的情况,但是并查集只有合并操作,没有删除操作,由于进行了路径压缩,因此删除的时候难以确定应该修改哪些节点。但是我们可以逆向操作,我们可以逆向遍历查询,遇到删除操作如果是逆序的话则是合并操作,这样就能用并查集进行处理了。确定了大方向后,我们首先读入初始化的边存入数组和集合中,然后存储后期的查询,然后对应后期遗忘的边存入集合方便后续判断。然后才开始初始化关系,注意后期要删除的边不要初始化。然后在存储查询的时候要注意,遗忘中可能包括不是初始化时的操作,是间接关系,是不需要执行并操作的,然后也会出现重复的遗忘,我们要执行加边的是第一次出现的遗忘,因此需要将重复的遗忘从查询中删除。然后要注意重写类的equals方法,传入的参数需要与父类一致,都是Object类,然后hashcode也需要重写,否则集合会判断两者不一样。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Stack;

public class Relationship {
    static int[] parent;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int q = in.nextInt();
        int x,y,type;

        HashSet<Node> initset = new HashSet<>();//存储初始化的边
        HashSet<Node> deleteSet = new HashSet<>();//存储后期遗忘的边
        Node[] initNodes = new Node[m];
        ArrayList<Node> queryNodes = new ArrayList<>();
        ArrayList<Integer> types = new ArrayList<>();
        Stack<String> ans =new Stack<>();
        Node node;
        parent = new int[n+1];
        for(int i=1;i<=n;i++){
            parent[i] = i;
        }

        for(int i=0;i<m;i++){
            x = in.nextInt();
            y = in.nextInt();
            initset.add(new Node(x,y));
            initNodes[i] = new Node(x,y);
        }

        for(int i=0;i<q;i++){
            type = in.nextInt();
            x = in.nextInt();
            y = in.nextInt();

            
            if(type == 1) {
                if(deleteSet.contains(new Node(x,y))){//我们只需保留第一个出现的遗忘
                    types.add(type);
                    queryNodes.add(new Node(x,y));
                }
                deleteSet.add(new Node(x,y));
            }
        }

        for(int i=0;i<m;i++){
            node = initNodes[i];
            if(!deleteSet.contains(node)){
                union(node.x, node.y);
            }
        }

        for(int i=queryNodes.size()-1;i>=0;i--){
            node = queryNodes.get(i);
            if(types.get(i)==1){
                if(initset.contains(node)){
                    union(node.x, node.y);
                }
            }else{
                if(find(node.x)==find(node.y)){
                    ans.push("Yes");
                }else{
                    ans.push("No");
                }
            }
        }
        
        while(!ans.isEmpty()){
            System.out.println(ans.pop());
        }

        in.close();
    }

    static void union(int i,int j){
        int i_fa = find(i);
        int j_fa = find(j);

        parent[i_fa] = j_fa;
    }

    static int find(int i){
        if(parent[i] == i){
            return i;
        }else{
            parent[i] = find(parent[i]);
            return parent[i];
        }
    }
}

class Node{
    int x;
    int y;

    public Node(int x,int y){
        this.x = x;
        this.y = y;
    }

    //需要传入的是Object类,不然不符合重写的要求
    @Override
    public boolean equals(Object obj){
        Node node = (Node) obj;
        if((x==node.x && y==node.y) || (x==node.y && y==node.x)){
            return true;
        }

        return false;
    }

    //必须重写Hashcode方法,不然会比较为不相同
    public int hashCode(){
        return 1;
    }
}

标签:node,Node,Scanner,int,美团,2024,new,public,3.9
From: https://www.cnblogs.com/xiqin-huang/p/18063786

相关文章

  • 2024.03.07
    今天是周四,寒假没碰乒乓球,上课练习基本功都拉胯了。今日代码时间半小时。Android架构Android操作系统是一个软件组件的栈,在架构图中它大致可以分为五个部分和四个主要层。 Android程序库这个类别包括了专门为Android开发的基于Java的程序库。这个类别程序库的示例包......
  • 省选联考 2024 重塑时光
    首先原问题显然是一个\(\text{DAG}\)计数的形式,施加枚举\(0\)度点集合\(S\)容斥的技巧是自然的。考虑\(k\)刀将其切割成\(t\)段后最终找到一种标号使得存在一种重排方案使其合法的方案数。段内的方案计算是容易的,要求它们所有关系顺序即可,可以快速求出构成一个段的集合......
  • 2024 年春节集训 _ 第一课 - 期望类型动态规划
    可能会用到的记号:\([P]=\begin{cases}1&(P成立)\\0&(P不成立)\end{cases}\)期望概率\(\texttt{dp}\)\(\texttt{dp}\)的变形当中最为简单易懂但是又思路又最为清奇。与之相关的难题数不胜数。考场上可以想出正解的都是超级神仙。粗浅的提一句,离散变量,也......
  • 2024 年春节集训 _ 第二课 - 数据结构优化动态规划
    【例题\(1\)】递增子序列\(\color{white}{link}\)考虑\(dp.\)\(dp[i][j]\)表示以元素\(i\)为结尾,长度为\(k\)的方案数。那么显而易见就有一个转移方程:\[dp[i][j]=\sum_{a[k]<a[i],\k<i}dp[k][j-1]\]先抛去第二维度的\(j\),这是可以做一个关于\(a[i]\)值的大......
  • 2024 年春节集训 _ 第三课 - 莫比乌斯反演
    练习\(5\)\(\color{orange}{\texttt{E->link}}\)求\[\sum_{i=1}^n\sum_{j=1}^mlcm(i,j)\]\(n,m\leq10^7,\T\leq10^4\)贴个照片。及其丑陋的照片(我的草稿)如上化简最后可以得到\[\sum_{d=1}^nd\sum_{k=1}^{\left[\dfrac{n}{d}\right]}\mu(k)k^2......
  • 20240309
    瑞士轮思路:快排会g,所以要归并排序defineintlonglong会g,关掉快排函数:stable_sort,用法和sort一样#include<bits/stdc++.h>usingnamespacestd;//#defineintlonglongstructinf{intscore;intid;intforce;};boolcmp(infa,infb){if......
  • 2024Windows11专业版产品永久密钥
    Windows11专业版是Windows11操作系统的商业版本,面向中小型企业和技术爱好者。它在Windows11家庭版的基础上增加了许多功能,可帮助企业和个人提高工作效率和安全性。主要功能:**加入域和AzureAD:**可将设备加入到ActiveDirectory域或AzureAD中,以便进行集中管理......
  • 2024Windows11专业工作站版产品永久密钥
    Windows11专业工作站版是Windows11操作系统的专门版本,面向需要更高性能、可靠性和安全性的大型企业和专业人士。它在Windows11专业版的基础上增加了许多功能,可帮助用户更有效地完成工作。主要功能:**更高的性能:**支持最多4个CPU和6TB内存,可满足苛刻应用程序的......
  • P10238 [yLCPC2024] F. PANDORA PARADOXXX 题解
    分析考虑时光倒流。对于需要合并的两个连通块\(x,y\),其合并之后的最远点对距离一定是合并之前的两组点对中产生的。在合并的时候枚举点对,取距离最大值即可。由于我们是倒着来的,所有连通块的最远点对距离最大值不减,所以能直接在合并之后取最大值。维护连通块用并查集即可。复杂......
  • P10237 [yLCPC2024] E. Latent Kindom 题解
    分析一眼了非最优解。考虑二分答案。对于二分出来的中位数\(x\),到\(a_i\)和\(a_j\)里边又去二分。得到两个序列中不超过\(x\)的数的数量。若这个数量\(cnt\ge\lceil\frac{len_{i}+len_{j}}{2}\rceil\),则\(x\)可能成为中位数,然后继续二分即可。把序列离散化,复杂度......