京东笔试

1. 最小战力

你在玩一款游戏,在游戏中你不断地打倒敌人,并强化自己的战斗力。
这个游戏中没有小怪,只有若干个 boss,你把所有 boss 全部打败即完成游戏。
打 boss 的顺序可以自选。为了让你们计算起来更加轻松,我大大简化了每个 boss 的属性,
每个 boss 只有两项属性:
击败它需要的战斗力数值(大于等于该数值即可击败)、击败它之后,
你可以永久获得的战斗力增加数值。在游戏的开始,你可以获得一定的战斗力,
且这个战斗力与你花的钱成正比。你当然想尽可能地省钱,
因此请你计算出能够通关的的前提下,一开始获得的最小战斗力。

输入描述

第一行整数 n,表示 boss 数量。1 <= n <= 100000
后面 n 行,每行两个空格隔开的整数 x, y,表示击败这个 boss 需要的战斗力数值,击败它之后,你可以永久获得的战斗力增加数值。0 <= x, y <= 1000000000。

输出描述

一个整数,表示能通关的情况下,一开始获得的最小战斗力数值。

100%。

public static void minInputVal() {
    Scanner scanner = new Scanner(System.in);
    int number = Integer.parseInt(scanner.nextLine().trim());
    List<int[]> vals = new ArrayList<>();
    for (int i = 0; i < number; i++) {
        String[] s = scanner.nextLine().trim().split(" ");
        vals.add(new int[]{Integer.parseInt(s[0]), Integer.parseInt(s[1])});
    }
    vals.sort(new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
            if(o1[0] != o2[0]) return o1[0] - o2[0];
            return o2[1] - o1[1];
        }
    });

    int money = 0, initMoney = 0;
    for (int[] val : vals) {
        if(money < val[0]){
            initMoney += val[0] - money;
            money = val[0];
        }
        money += val[1];
    }
    System.out.println(initMoney);
}

2. 序列重排

给一个长度为n的序列A,你可以将序列中的元素按任意顺序重新排列,请你找到一种排列方式使得相邻两个数的差值之和最大,你只需要输出这个最大值即可。

输入描述

第一行整数 n,表示 boss 数量。1 <= n <= 100000
后面 n 行,每行两个空格隔开的整数 x, y,表示击败这个 boss 需要的战斗力数值,击败它之后,你可以永久获得的战斗力增加数值。0 <= x, y <= 1000000000。

输出描述

一个整数,表示能通关的情况下,一开始获得的最小战斗力数值。

采用最粗暴做法,通过27%,超时。还是记录下:

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = Integer.parseInt(scanner.nextLine().trim());
    String[] s = scanner.nextLine().trim().split(" ");
    List<Integer> vals = new ArrayList<>();
    HashMap<Integer, Integer> visited = new HashMap<>();
    for (int i = 0; i < n; i++) {
        int key = Integer.parseInt(s[i]);
        vals.add(key);
        visited.put(key, visited.getOrDefault(key, 0) + 1);
    }
    vals.sort(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 - o2;
        }
    });

    List<List<Integer>> res = new ArrayList<>();
    dfs(vals, new ArrayList<Integer>(), res, visited);

    int maxVal = Integer.MIN_VALUE;
    for (List<Integer> re : res) {
        maxVal = Math.max(maxVal, calcSum(re));
    }
    System.out.println(maxVal);
}

private static int calcSum(List<Integer> temp) {
    int res = 0;
    for (int i = 1; i < temp.size(); i++) {
        res += Math.abs(temp.get(i - 1) - temp.get(i));
    }
    return res;
}

private static void dfs(List<Integer> vals, ArrayList<Integer> temp, List<List<Integer>> res,
                        HashMap<Integer, Integer> visited) {
    if(temp.size() == vals.size()){
        res.add(new ArrayList<>(temp));
        return;
    }

    for (int i = 0; i < vals.size(); i++) {
        int key = vals.get(i);
        if(i != 0 && vals.get(i - 1) == key) continue;
        if(visited.get(key) > 0){
            visited.put(key, visited.get(key) - 1);
            temp.add(key);
            dfs(vals, temp, res, visited);
            temp.remove(temp.size() - 1);
            visited.put(key, visited.get(key) + 1);
        }
    }
}

该怎么做?

#京东##笔经#
全部评论
第一题 JavaScript 版: function method(arr) {     arr.sort((a, b) => {         if (a[0] !== b[0]) return b[0] - a[0];         return a[1] - b[1];     });     let res = arr[0][0];     arr.shift();     for (const boss of arr) {         res -= boss[1];         if (res < boss[0]) res = boss[0];     }     return res; } let n = readInt(); const list = []; while (n--) {     const row = read_line().trim().split(' &(5528)#39;).map(item => parseInt(item));     list.push(row); } print(method(list));
2 回复 分享
发布于 2021-09-11 23:04
序列重排其实是数学题,就考虑如果序列无限长,那就是低高低高这样无限排序,那么最大值就是每一个高减去每一个低两次,但是有限,就需要考虑有限是奇数还是偶数的情况,先排序分为高低数组,然后高的减低的乘2,然后看奇数偶数来把多加的高多减的低来删掉。 python题解 numbers = [5 ,1, 2,2,2] mid = len(numbers)//2 numbers = sorted(numbers) low = numbers[:mid] high = numbers[mid:] temp = 2*(sum(high)-sum(low)) if len(numbers)%2 == 0:     ans = temp - high[0]+low[-1] else:     ans = temp - high[1]-high[0] print(ans)
1 回复 分享
发布于 2021-09-11 21:19
序列重排,同27
点赞 回复 分享
发布于 2021-09-11 20:56
序列重排用回溯 45 超时了
点赞 回复 分享
发布于 2021-09-11 21:07
排序,把从中间分成两半,前面的数➖两遍,后面的数加两遍,然后分奇偶,分别是前面的第一个数多减一次,后面第一个数多加一次。或者后面的第一个数多加两次
点赞 回复 分享
发布于 2021-09-11 21:12

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳&nbsp;&nbsp;yidao,试用期&nbsp;6&nbsp;个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
头像
11-09 17:30
门头沟学院 Java
TYUT太摆金星:我也是,好几个华为的社招找我了
点赞 评论 收藏
分享
评论
5
22
分享
牛客网
牛客企业服务