百度笔试0410

最佳优惠

时间限制: 3000MS

内存限制: 589824KB

题目描述:

现在给你一张优重券。优重券上有两个正整数 L L L R R R

该优重券的使用规则是:

  • 你可以任意选取一个位于 [ L , R ] [L, R] [L,R] 之间的正整数(不妨令其为 x x x) ,抵扣 x x x x x x各个数位上的数字之和的乘积的金额。

比如当你选择数字69时,你可以抵扣的金额为
69 ∗ ( 6 + 9 ) = 1035 69*(6+ 9)= 1035 69(6+9)=1035

现在询问你最大可以利用手中这张优重券抵扣多少金额?

输入描述

一行, 给出两个整数L R以空格隔开,代表手中优惠券上的数。
1 ≤ L ≤ R ≤ 1 e 5 1≤L≤R≤1e5 1LR1e5

输出描述

输出行,代表最大优重金额。

样例输入
36

样例输出
36

提示

样例解释1
选取数字为 3 3 3的折扣金额是 3 ∗ 3 = 9 3*3=9 33=9,数字为 4 4 4的折扣金额是 4 ∗ 4 = 16 4*4=16 44=16,数字为 5 5 5
折扣金额是 5 ∗ 5 = 25 5*5=25 55=25,数字为 6 6 6的折扣金额是 6 ∗ 6 = 36 6*6=36 66=36,故最大折扣金额为 36 36 36.

输入样例2
11 31
输出样例2
319

样例解释2
选取数字为 29 29 29的折扣金额是 29 ∗ ( 2 + 9 ) = 319 29 * (2+9)=319 29(2+9)=319,可以证明这是手上优惠金额最大的一张优惠券。


static int miniTask(int input) {
    
    
        int out = 0;

        int t = input;
        while (t > 0) {
    
    
            out += t % 10;
            t /= 10;
        }

        out = out * input;
        return out;
    }

    static int findMax(int L, int R, int step) {
    
    
        int out = 0;

        if (step == 1) {
    
    
            for (int i = L; i < R; i++) {
    
    
                out = Math.max(miniTask(i), out);
            }
        } else {
    
    
            int left = (L / step + 1) * step - 1;
            for (; left <= R; left += step) {
    
    
                out = Math.max(out, miniTask(left));
            }
            left -= step;

            out = Math.max(out, findMax(left, R, step / 10));
        }

        return out;
    }

    static int task1() {
    
    
        Scanner scanner = new Scanner(System.in);

        int L = scanner.nextInt();
        int R = scanner.nextInt();
        int out = Math.max(miniTask(L), miniTask(R));

        int mark = 1;
        int dis = R - L;
        if (dis < 10) {
    
    
            out = Math.max(out, findMax(L, R, mark));
        } else {
    
    
            while (dis >= 10) {
    
    
                mark *= 10;
                dis /= 10;
            }

            out = Math.max(out, findMax(L, R, mark));
        }

        return out;
    }



玩具士兵

时间限制:3000MS
内存限制:589824KB

题目描述:

小明买了一些玩具士兵,他邀请小红一起玩。他总共有n个士兵,刚开始时,这 n n n个士兵被排成一列,第i个士兵的战斗力为 h j h_j hj。然后小明和小红开始给它们排序。

二人总共进行了 m m m次操作。小明的每次操作会选择一个数k,将前 k k k个士兵按战斗力从小到大排序。

小红的每次操作会选择一个数 k k k,将前 k k k个士兵按战斗力从大到小排序。

请问所有操作结束后从前往后每个士兵的战斗力是多少?

输入描述

第一行有两个整数 n 、 m n、m nm 1 ≤ n m ≤ 2 × 1 0 5 1≤nm≤2×10^5 1nm2×105),分别代表士兵的数量与操作次数。第二行有n个整数 h 1 , h 2 , … … , h n h_1,h_2,……,h_n h1h2……hn − 1 0 9 ≤ h j < 1 0 9 -10^9≤h_j<10^9 109hj<109),代表初始状态下从前往后各个士兵的战斗力。

接下来 m m m行按顺序给出所有操作,每行有两个整数 t 、 k t、k tk 1 ≤ t ≤ 2 , 1 ≤ k ≤ n 1≤t≤2,1≤k≤n 1t21kn),t=1 代表是小明的操作,否则是小红的操作, 代表是小明的操作,否则是小红的操作, 代表是小明的操作,否则是小红的操作,k 代表对前 代表对前 代表对前k$个士兵进行排序。

输出描述

输出 n n n个整数,代表所有操作结束后从前往后每个士兵的战斗力。

样例输入
4 2
1 2 4 3
2 3
1 2

样例输出
2 4 1 3


思路:如果后一个操作的k大于之前的任何一个操作,则之前的任何一个操作不会影响最终的结果

#输入测试用例

n,m = 4,2
tgt = [1,2,4,3,9,8,0]
ops = [[1,5],[1,7],[2,2],[2,3],[1,2]]

从后向前搜索所有操作,使用 c u r m a x cur_max curmax记录当前最大的 k k k

cur_max = [ops[-1]]

#从后向前,找到对最终结果能产生影响的操作

ops.reverse()
for op in ops:

    # 如果该操作大于“当前最大的k”,则该记录能对最终结果造成影响
    if cur_max[-1][1]<op[1]:
        cur_max.append(op)

cur_max.reverse()

#依据 c u r m a x cur_max curmax记录的操作,对玩具士兵进行操作

for op in cur_max:
    temp = tgt[:op[1]]
    temp.sort(reverse=(op[0]!=1))
    tgt[:op[1]]=temp

print(tgt)

Supongo que te gusta

Origin blog.csdn.net/weixin_43338969/article/details/130158308
Recomendado
Clasificación