美团笔试总结

1.乒乓球

获胜规则如下:一方至少赢得11分,且超过对方2分,获得胜利。

小美得a分,小团b分,最理想的情况下,小美至少还要得多少分才可以赢。

样例输入:

30 31

样例输出:

3

参考解答:

import java.util.Scanner;

/**
 * @author Halu
 * @create 2022-09-03 11:36
 */
public class countGame {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        System.out.print(countGame(a,b));

    }

    public static int countGame(int a, int b) {
        int res = 0;
        
        if (a>=11){
            if (a>=b+2){return 0;}
            else{return b+2-a;}
        }else{ // a<11
            if (a>=b+2){return 11-a;}
            else if ( (a<b+2) && (b+2>=11) ) return b+2-a;
            else if ( (a<b+2) && (b+2<11) ) return 11-a;
        }

        return res;

    }

}

2.二叉树

n个节点的树,里面存字母。判定各个子树含有多少种类型的字母。

 输入描述:

 输出描述:

 样例输入:

6 
1 2 2 1 4
ABCCAD

 样例输出:

4 3 1 2 1 1

参考解法:

package exer1;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author Halu
 * @create 2022-09-04-20:42
 */
class countAlpha {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] relation = new int[n-1];
        System.out.println();
        for (int i = 0; i <n-1 ; i++) {
            relation[i]=in.nextInt();
//            System.out.print(relation[i]+" ");
        }
        in.nextLine();
        String s = in.nextLine();
        for (int i = 0; i < s.length(); i++) {
//            System.out.print(s.charAt(i)+" ");
        }
        int[] res = countAlpha(n,relation,s);
        for (int resNum:res) {
            System.out.print(resNum+" ");
        }
    }

    public static int[] countAlpha(int n, int[] relation, String s){
        int[] res = new int[n];
        
        boolean[][] graph = new boolean[n][n];//graph用来存relation的父子关系,从父节点可到子节点该位置为true
        for (int i = 0; i < n; i++) {
            Arrays.fill(graph[i],false);
        }
        // 遍历relation,把 x=relation[i](父节点),和子节点y=i+2 存到 graph[x][y]中
        for (int i = 0; i < n - 1; i++) {
            int x = relation[i]-1; // 父
            int y = i+1; // 子
            graph[x][y] = true;
        }

        for (int x = 0; x < n; x++) {//遍历1~n节点,找子节点,然后子节点递归
            boolean[] used = new boolean[26];
            used[s.charAt(x)-'A'] = true;
            for (int y = 0; y < n ; y++) {
                if (graph[x][y] == true){
                    char ch = s.charAt(y);
                    used[ch-'A'] = true;
                    used=countUsed(y,graph,s,used);
                }
            }
            int sum=0;
            for (int i = 0; i < 26; i++) {
                if (used[i]==true) sum++;
            }
            res[x] = sum;
        }

        
        return res;
    }

    public static boolean[] countUsed(int start, boolean[][] graph, String s, boolean[] used){
        int n=graph.length;
        // 遍历graph
        // 维护一个used标记种类
//        boolean[] used = new boolean[26];
            for (int y = 0; y < n; y++) {
                if (graph[start][y] == true){
                    char ch = s.charAt(y);
                    used[ch-'A'] = true;
                    countUsed(y,graph,s,used);
                }
            }

            return used;
    }
}

 类似参考解答:

力扣1519

class Solution {
    public int[] countSubTrees(int n, int[][] edges, String labels) {
        /*
            后序遍历
        */
        List<Integer>[] points = new List[n];
        for(int i = 0; i < n; i++){
            points[i] = new ArrayList<>();
        }
        for(int[] p : edges){
            points[p[0]].add(p[1]);
            points[p[1]].add(p[0]);
        }

        int[] ls = new int[n];
        for(int i = 0; i < n; i++){
            ls[i] = labels.charAt(i) - 'a';
        }

        res = new int[n];
        visited = new boolean[n];
        visited[0] = true;
        dfs(0, points, ls);
        return res;
    }
    int[] res;
    boolean[] visited;
    private int[] dfs(int i, List<Integer>[] points, int[] ls){
        int[] curLs = new int[26];
        //添加自身节点
        curLs[ls[i]]++;
        for(int child : points[i]){
            /*
                判断是否已经遍历过该节点,如果遍历过,那么跳过
                因为这是无向图, 1 可以到 2,2 也可以到 1,因此,当 1 到 2 的时候,我们需要记录 1 已经访问
                这样,从 2 出发,就不会再到 1 了
            */
            if(visited[child]){
                continue;
            }
            visited[child] = true;
            int[] childLs = dfs(child, points, ls);
            for(int k = 0; k < 26; k++){
                curLs[k] += childLs[k];
            }
        }
        res[i] = curLs[ls[i]];
        return curLs;
    }
}

9.10 第三次笔试

1.刷题

n个题,小美正序做,小团逆序做。小美速度y题/小时,小团速度x题/小时。获胜规则,谁先写完第k题谁就获得胜利。

  • 输入:

第一行表示数据组数T,

接下来T行,每行包括四个正整数n,x,y,k。

  • 输出:共T行

小美获胜输出Win

小团获胜输出Lose

平局输出Tie

 

除法需要注意的点:算速度时间用 double 接收

import java.util.Scanner;

/**
 * @author Halu
 * @create 2022-09-10 16:38
 */
public class Meituan3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int[][] nums = new int[N][4];
        for (int i = 0; i < 3; i++) {
            nums[i][0]=in.nextInt();
            nums[i][1]=in.nextInt();
            nums[i][2]=in.nextInt();
            nums[i][3]=in.nextInt();
        }
        String[] res = tellWinner(nums);
        for (int i = 0; i < res.length; i++) {
            System.out.println(res[i]);
        }
    }

    public static String[] tellWinner(int[][] nums){
        String[] Winner = new String[nums.length];

        for (int i = 0; i < nums.length; i++) {
            int n = nums[i][0];
            int Vwin = nums[i][1];
            int Vlose = nums[i][2];
            int k = nums[i][3];

            
            double winTime = (double)k/Vwin;
            double loseTime = (double)(n+1-k)/Vlose;
            
            if (winTime<loseTime) Winner[i]= "Win";
            else if(winTime>loseTime) Winner[i]= "Lose";
            else Winner[i]= "Tie";
            
        }
        return Winner;
    }
}
// 牛客上的答案:除法转为乘法
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while(t-->0){
    long n = scanner.nextLong();
    long x = scanner.nextLong();
    long y = scanner.nextLong();
    long k = scanner.nextLong();
    if (k * y < x * (n - k + 1)) {
        System.out.println("Win");
    } else if (k * y == x * (n - k + 1)) {
        System.out.println("Tie");
    } else {
        System.out.println("Lose");
    }
}

2. 寻宝 

// 牛客上的答案
package mt.笔试;
/*
时间限制: 3000MS
内存限制: 589824KB
题目描述:
某天小美进入了一个迷宫探险,根据地图所示,这个迷宫里有无数个房间,序号分别为1、2、3、…、∞,入口房间的序号为1,任意序号为正整数x的房间都与序号2*x和2*x+1的房间之间各有一条路径,但是这些路径是单向的,即只能从序号为x的房间去到序号为2*x或2*x+1的房间,而不能从序号为2*x或2*x+1的房间去到序号为x的房间。在任何时刻小美都可以选择结束探险并离开迷宫,但是离开之后将无法再次进入迷宫。小美还提前了解了迷宫中宝藏的信息,已知宝藏共有n个,其中第 i 个宝藏在序号为pi的房间,价值为wi,且一个房间中可能有多个宝藏。小美为了得到更多的宝藏,需要精心规划路线,她找到你帮忙,想请你帮她计算一下,能获得的宝藏价值和最大值为多少。



输入描述
第一行一个正整数n,表示宝藏数量。

第二行为n个正整数p1, p2,...... pn,其中pi表示第 i 个宝藏在序号为pi的房间。

第三行为n个正整数w1, w2,...... wn,其中wi表示第i个宝藏的价值为wi。

数字间两两有空格隔开

1 ≤ n ≤ 40000, 1 ≤ pi <230, 1 ≤ wi ≤ 106。

输出描述
输出一个正整数表示能获得的宝藏价值之和的最大值。
 */
package ACM_Exercise;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * @author Halu
 * @create 2022-09-10 17:14
 */
public class Meituan302 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long[] pos = new long[n];
        long[] value = new long[n];
        for (int i = 0; i < n; i++) {
            pos[i] = in.nextLong();
        }
        for (int i = 0; i < n; i++) {
            value[i] = in.nextInt();
        }
        System.out.println(maxValue(pos, value));

    }

    public static int maxValue(long[] pos, long[] value){
        int sum=0;
        BigInteger maxSum = BigInteger.valueOf(0);

        HashMap<Long,Long> map = new HashMap();
        for (int i = 0; i < pos.length; i++) {
            if (map.containsKey(pos[i])){
                map.put(pos[i],map.get(pos[i])+ value[i]);
            }else {
                map.put(pos[i],value[i]);
            }
        }

        BigInteger[] dp = new BigInteger[pos.length];
        for (int i = 0; i < dp.length; i++) {
            dp[i]  = countValue(pos[i],map);
            maxSum = dp[i].compareTo(maxSum)>0?dp[i]:maxSum;
        }

        return maxSum.intValue();
    }

    public static BigInteger countValue(long aim, HashMap<Long,Long> map){
        LinkedList<Long> list = new LinkedList();
        while (aim!=1){
            list.add(aim);
            aim = aim/2;//加入目标节点及其父节点
        }
        list.add(1L);

        BigInteger maxV = BigInteger.valueOf(0);
        for (Long room:list) {
            if (map.containsKey(room)){
                maxV = maxV.add(BigInteger.valueOf(map.get(room)));
            }
        }
        return maxV;
    }
    
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值