第九届蓝桥杯-乘积最大 (含测试数据)

乘积最大

给定N个整数A1, A2, … AN。请你从中选出K个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数。
10e9+9
注意,如果X<0, 我们定义X除以1000000009的余数是负(-X)除以1000000009的余数。
即:0-((0-x) % 1000000009)
【输入格式】
第一行包含两个整数N和K。
以下N行每行一个整数Ai。
对于40%的数据,1 <= K <= N <= 100
对于60%的数据,1 <= K <= 1000
对于100%的数据,1 <= K <= N <= 100000 -100000 <= Ai <= 100000
【输出格式】
一个整数,表示答案。
【输入样例】

5 3
-100000
-10000
2
100000
10000

【输出样例】

999100009

再例如:
【输入样例】

5 3
-100000
-100000
-2
-100000
-100000

【输出样例】

​-999999829

0-( \ (0-x) \ \% 1000000009 \ ),这一句其实没什么卵用,比如x=-2,(-2)%1000000009本来就就等于-2,不用0-((0-x))

分情况讨论。

一、没有负数

       从大到小排序,然后直接乘就好了。

二、没有正数

       ①k为偶数,显然结果肯定是正数,所有数字从小到大排序,然后乘k个。

       ②k为奇数,结果肯定为负数,所有数字从大到小排序,然后乘k个。

三、既有正数也有负数

        先从大到小排好序。注意就是,负数如果参与计算,肯定是成对的。故可以从两边到中间,两个数一组,开始计算。

      ①以6 3  ,3 2 2 -1 -4 -5为例。

        第一步,3*2(-4) * (-5)小,所以sum = sum * (-4) * (-5) \ \ \ \ k = k-2;

        第二步,后面已经凑不齐两个负数了,这时候从只计算左边就行了,sum = sum * 3 \ \ \ k = k -1 。

        第三步,同上一步,sum = sum * 2 \ \ \ k = k -1,这时候k=0了,停止计算,输出sum。

      ②以9 5,9 8 7 4 2 -3 -4 -5 -6为例。

       第一步,比9*8  比  (-5)*(-6)大,所以sum = sum * 9 * 8 \ \ \ \ k = k-2,                      

       第二步,7 * 4  比  (-3 )* (-4)大,所以sum = sum * 7 *4 \ \ \ \ k=k-2,                

       第四步,sum = sum * 2 \ \ \ \ k=k-1,k=0,输出sum                             

        但是这样是错的。 显然9 * 8 * 7 * (-5)*(-6)才是最优解,正确计算顺序如下:       

        第一步,比9*8  比​  ​​​​​​(-5)*(-6)大,所以sum = sum * 9 \ \ \ \ k = k-1,                     

        第二步,8 * 7 比 (-5)*(-6)大,所以sum = sum * 8 \ \ \ \ k = k-1

        第三步,7 * 4 比 (-5)*(-6)小,所以sum = sum * (-5)*(-6) \ \ \ \ k = k-2

        第四步,7 * 4 比  (-3)*(-4)大,所以sum = sum * 7 \ \ \ \ k = k-1。k=0了,输出sum就是正确答案了。

#include <iostream>
#include <algorithm>
#include <vector>
#define LL long long
using namespace std;
const LL MOD = 1000000009;
int main()
{
    int n, k;
    vector<LL> v;
    cin >> n >> k;
    int Min = INT32_MAX, Max = INT32_MIN;
    int num_fu;
    for (int i = 0, t; i < n; i++)
    {
        cin >> t;
        if (t < 0)
            num_fu++;
        Min = min(Min, t);
        Max = max(Max, t);
        v.push_back(t);
    }
    LL sum = 1;
    if (Min >= 0) //没有负数
    {
        sort(v.begin(), v.end(), [](int a, int b) { return (a) > (b); }); //从大到小排列
        for (int i = 0; i < k; i++)
            sum = (sum * v[i]) % MOD;
    }
    else if (Max <= 0) //没有正数
    {
        if (k & 1) //k为奇数时,从大到小排列
        {
            sort(v.begin(), v.end(), [](int a, int b) { return (a) > (b); }); //从大到小排列
            for (int i = 0; i < k; i++)
                sum = (sum * v[i]) % MOD;
        }
        else //k为偶数时
        {
            sort(v.begin(), v.end());
            for (int i = 0; i < k; i++)
                sum = (sum * v[i]) % MOD;
        }
    }
    else //正负数都有
    {
        sort(v.begin(), v.end(), [](int a, int b) { return (a) > (b); });
        int l = 0, r = n - 1;
        while (k)
        {
            if (v[r - 1] < 0 && k != 1)
            {
                LL t1 = v[l] * v[l + 1];
                LL t2 = v[r] * v[r - 1];
                if (t1 > t2)
                {
                    sum = (sum * v[l]) % MOD;
                    l += 1;
                    k -= 1;
                }
                else
                {
                    sum = (sum * v[r] % MOD * v[r - 1] % MOD);
                    r -= 2;
                    k -= 2;
                }
            }
            else
            {
                sum = (sum * v[l]) % MOD;
                l++;
                k -= 1;
            }
        }
    }
    cout << sum << '\n';
    //system("pause");
    return 0;
}

oj跑分:https://www.dotcpp.com/oj/problem2280.html

一些自己写测试数据:

5 5
1 2 3 4 5
120

8 5
6 7 1 1 -5 -6 -7 -8
11760

10 5
-1 -2 5 5 -6 -7 -9 6 -5 -7
15876

10 9
-65 95 66444 -36516 0 0 664 2626 -5 -6
0

8 5
9 8 7 6 5 -1 -2 -3 -4
15120

8 5
-9 -8 -7 -6 -5 1 2 3 4
9072

9 4
-1 -2 -3 -4 -5 -6 -7 -8 -9

9 4
1 2 3 4 5 6 7 -5 -6
1260

9 5
9 -1 -2 -3 -4 -5 -6 -7 -8
15120

38 5
-21238 -8855 -8365 10450 5853 -1142 -20537 -8945 2997 -20976 21655 -18457 28881 9725 2446 -840 -16907 -23611 -12456 29533 -28223 31597 -12212 7578 7629 -12279 -24388 12329 2331 22114 26928 21652 24337 5598 -14097 -4683 15260 -2747
467887151

103 73
-103 -676 448 228 758 -271 165 164 -623 510 35 -951 952 -113 115 614 199 -696 -789 227 -261 -570 -828 215 270 -839 -229 277 338 -390 244 -949 -703 720 -31 -883 -965 43 -481 597 120 -80 -600 793 -226 430 -615 916 -463 868 157 740 -687 595 324 119 615 882 -683 -689 -175 975 -133 -354 -46 781 -328 -942 962 112 430 -651 -752 571 -959 -759 -2 59 -341 399 -44 -777 -575 697 118 932 -279 131 486 -460 548 161 779 856 888 92 -610 -393 571 813 277 373 -990
699589110

283 151
-1283 -11166 30694 20573 11392 -9136 11387 -22317 26052 -29896 -17295 24566 -22684 -29203 32440 -13825 -3974 -1811 -6783 -5929 -15416 8220 31459 17500 -19481 -25303 10199 25117 19654 14018 6591 10500 8334 7598 -22006 26173 -758 23616 23371 19461 23862 -29297 24191 4656 -27322 25615 22217 26277 11682 -20793 -23123 11744 13123 24294 19130 4975 10403 -28510 -20881 27254 16129 10943 11487 -24108 -24651 -22394 19356 -29275 13221 -724 14904 -21476 29161 31078 24340 31032 -2594 -3997 1799 4832 -5647 -14907 16859 19446 -7846 30419 3790 -23210 -12431 -1105 -22801 24766 16549 27504 17483 7179 24697 22338 18711 -26361 -17102 -15787 8578 -2314 4125 -22502 1423 -22352 2835 27391 14259 9459 1294 -24663 24921 940 8868 -11812 16222 -21580 -28700 -4078 -7830 10038 17906 3859 -10310 -27872 32088 23364 32424 30295 -29872 -29446 10602 -17848 -25619 7218 21039 -11959 461 -11380 -20748 -18204 30430 8656 2316 10049 9082 2840 -5293 31382 13194 -16503 -16992 -24605 -809 27626 -24845 -6894 -21288 25026 23693 4787 19851 -18723 -10799 -9261 23049 -5256 1331 16814 -17040 -19005 31570 -25501 10175 -7395 18740 18677 17770 -21487 1784 1990 -1817 -1068 -9392 28083 27785 -6196 14050 -12402 -15914 10491 -4872 -28239 4511 -9796 15377 -32425 -7745 -20266 7902 -4723 24989 -31385 -7877 9397 5105 12242 -29201 -15113 27827 -3818 -20097 -30238 14090 2379 26053 -29240 -13906 27186 -12804 -30638 23197 12079 -4696 -31594 -17709 12456 -14160 28525 7419 -6743 -24429 -25416 -13107 -13256 25510 -29860 30645 -30939 5092 4027 15765 584 25478 -32733 -20380 -15894 26079 -20460 -21701 -30754 -6835 -31457 1217 12959 2750 -27717 -11380 -20112 -13356 -20663 629 -1103 18210 13932 -19346 -11274 -12852 -32171 -20297 -22081 -32492 -6477 -7248 13385 -32330 -8004 -7439 20684 -17726
889629030

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值