蓝桥杯_防御力 java

题目描述

小明最近在玩一款游戏。对游戏中的防御力很感兴趣。

我们认为直接影响防御的参数为"防御性能",记作 d ,而面板上有两个防御值 AB ,与 d 成对数关系,A=2dB=3d(注意任何时候上式都成立)。

在游戏过程中,可能有一些道具把防御值 A 增加一个值,有另一些道具把防御值 B 增加一个值。

现在小明身上有n1 个道具增加 A 的值和 n2 个道具增加 B 的值,增加量已知。

现在已知第 i 次使用的道具是增加 A 还是增加 B 的值,但具体使用那个道具是不确定的,请找到一个字典序最小的使用道具的方式,使得最终的防御性能最大。

初始时防御性能为 00,即 d=0,所以A=B=1。

输入描述

输入的第一行包含两个数 n1,n2,空格分隔。

第二行 n1 个数,表示增加 A 值的那些道具的增加量。

第三行 n2 个数,表示增加 B 值的那些道具的增加量。

第四行一个长度为 n1+n2 的字符串,由 0 和 1 组成,表示道具的使用顺序。0 表示使用增加 A 值的道具,1 表示使用增加 B 值的道具。输入数据保证恰好有 n1 个 0,n2 个 1 。

其中,字符串长度 ≤2×106≤2×106,输入的每个增加值不超过 230230。

输出描述

对于每组数据,输出 n1+n2+1 行。

n1+n2 行按顺序输出道具的使用情况,若使用增加A 值的道具,输出 ,Axx 为道具在该类道具中的编号(从 1 开始)。若使用增加 B 值的道具则输出Bx

最后一行输出一个大写字母 E 。

输入输出样例

示例
输入
1 2
4
2 8
101
输出
B2
A1
B1
E

运行限制

  • 最大运行时间:1s

  • 最大运行内存: 256M

当连续使用道具A或者连续使用道具B时,比如连续使用道具A公式是log2​(1+A1+A2+⋯),它的d其实是不变的。当A和B交替使用时d才会不同。这里用数学公式证明的话相当的复杂,我个人认为较快的方法是用具体的数带进去进行估算。然后我们得出当A排序由小到大,B排序由大到小这样得出的d是最大的。
因为d=log2(A)=log3(B)这个任何时候都成立,在对A和B进行交叉操作增加x值的时候,比如先对A操作,肯定是先增加较大的ai收益最大,因为先增加大的ai会使d在这一次增加幅度较大,同时使B也增加较大,对于下一次增加B会有更好的收益;对B操作也是类似上面,也就是说,对ai和bi进行一个结构体排序,先按值的大小排序再按下标顺序(字典序)排序。当然还有注意一种情况,就是无论用什么顺序达到的收益都是一样的,这是在什么情况下会这样呢,很明显,在连续操作某一防御值的时候,不管先增加较大的还是较小的,在操作另一防御值之前,该防御值增加的总值都是一样的,对于d和另一防御值的总影响值也是一样的,因此这个时候就需要按字典序顺序操作了。

代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class 防御力 {
      //存储a和b的数组遍历时必须要一个升序一个降序,
    //因为要使得每一次的防御力最大,而不是全部升序或者全部降序
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n1 = scanner.nextInt();
        int n2 = scanner.nextInt();
        //采用list集合,为了后续减少一个遍历原数据的位置,直利用一个indexOf函数
        List<Integer> lista = new ArrayList<>();
        int[] copya = new int[n1];
        for (int i = 0; i < n1; i++) {
            lista.add(scanner.nextInt());
            copya[i] = lista.get(i);
        }

        List<Integer> listb = new ArrayList<>();
        int[] copyb = new int[n2];
        for (int i = 0; i < n2; i++) {
            listb.add(scanner.nextInt());
            copyb[i] = listb.get(i);
        }

        Arrays.sort(copya);
        Arrays.sort(copyb);
        String str = scanner.next();
        int indexa = 0;
        int indexb = n2 - 1;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch == '0') {
                if (indexa < n1) {
                    System.out.println("A" + String.valueOf(lista.indexOf(copya[indexa]) + 1));
                }
                indexa++;
            } else {
                if (indexb >= 0) {
                    System.out.println("B" + String.valueOf(listb.indexOf(copyb[indexb]) + 1));
                }
                indexb--;
            }
        }
        System.out.println("E");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值