Java——百度2021校招C /PHP研发工程师笔试卷(第三批)[编程题]牛牛的硬币

牛牛有一个特殊的硬币,它有百分之p的概率正面朝上,否则反面朝上。牛牛现在有2*n个数字a[1]~a[2*n], 要把这2*n个数字分成n组,每组2个数字。然后对于每一组,牛牛会投掷他这个特殊的硬币,如果硬币正面朝上,牛牛会将答案加上这组两个数中较大的那个数,否则牛牛会将答案加上这组两个数中较小的那个数。现在问你怎么分组,能使牛牛最后的得到的答案的期望最大。请输出这个最大期望。

输入描述:

第一行是一个整数n和一个整数p(1<= n <=1e6 , 0<= p <=100)

接下来一行有2*n个数组a[i](0<= a[i] <= 1e11)

输出描述:

输出最大期望,如果最大期望恰好是整数,则直接输出这个整数,否则,按百分数的形式输出这个百分数。

输入例子1:

3  0
1 3 3 2 2 3

输出例子1:

6

例子说明1:

我们可以把它分为(1,3)(2,2)(3,3)三组,最后得到的期望是600%,没有比这期望更大的分组方式了,因为是整数,所以直接输出6即可

输入例子2:

1 20
1 2

输出例子2:

120%

例子说明2:

只有(1,2)一种分组方式,有百分之20的可能+2,有百分之80的可能+1,所以期望是120%,不是整数,所以输出120%

解题思路:

以下叙述中,大数代表字面值大的数,小数表示字面值较小的数

若输入的几率p>=50 说明每组有超过一半的几率选到较大的数,此时应该将大数与小数放在一组

若输入的几率p<50,说明每组有超过一半的几率选到较小的数,此时应将大数与大数放一组,小数与小数放一组

代码:

import java.util.*;


public class test2 {
    public static void main(String[] args) {

//        System.out.println(1*(1-20/100)+2*(80/100));
//        System.out.println(20/100);
        Scanner scanner = new Scanner(System.in);
        String lineOne = scanner.nextLine();
        String lineTwo = scanner.nextLine();
        int expectation = getExpectation(lineOne,lineTwo);
        if (expectation%100==0){
            System.out.println(expectation/100);
        }else {
            System.out.println(expectation+"%");
        }
    }

    private static int getExpectation(String lineOne,String lineTwo){
        String[] strings1 = lineOne.split(" ");
        int p = Integer.parseInt(strings1[1]);
        int expectation = 0;
        ArrayList<Integer> arrayList = getList(lineTwo);
        arrayList.sort(Comparator.naturalOrder());
        if (p>=50){//每组超过百分之50的几率选到大数
            for (int i = 0; i < Integer.parseInt(strings1[0]); i++) {
                expectation += arrayList.get(i)*(100-p)+arrayList.get(arrayList.size()-1-i)*p;
            }
        }else {
            for (int i = 0; i < Integer.parseInt(strings1[0]); i++) {
                expectation += arrayList.get(2*i)*(100-p)+arrayList.get(2*i+1)*p;
            }
        }
        return expectation;
    }

    private static ArrayList<Integer> getList(String lineTwo){
        String[] strings2 = lineTwo.split(" ");
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (String s:strings2
             ) {
            arrayList.add(Integer.parseInt(s));
        }
        return arrayList;
    }
}

运行结果:

首先输入2个例子:

1 20
1 2
120%

3 0
1 3 3 2 2 3
6

接着验证其他情况:

1 60
1 2
160%

结果正确

总结:

做这道题的过程中,我居然忘了int类型相除最后结果是向下取整的int(20/100输出结果为0),导致代码调试了很久,基础还是不够牢固。

我会分享一些有意思的算法题,与君共勉。如果有更好的解题思路欢迎分享,如果本文有不正确的地方欢迎指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值