CF problem: (D) Maximum Product Strikes Back

Problem - D - Codeforces

 

 

 

Example
input
5
4
1 2 -1 2
3
1 1 -2
5
2 0 -2 2 -1
3
-2 -1 -1
3
-1 -2 -2

 

output
0 2
3 0
2 0
0 1
1 0

 

 

最近赛中敲不出代码, 赛后倒是镇静了, 我也醉了

简述下思路及变量意义: 

这里采取从前到尾遍历,由于数据范围不能完全连乘2e5个的2, 所以我们采取计数方法,

num表示绝对值为2的个数, sign表示当前是正负数, min是从上一个0到现在连乘绝对值最小的负数

带有res的4个变量是截止到1~i的最优方案: res是乘积最大的2的个数, resl是连乘的左边界, resr是连乘的右边界, res0是前面最近所在0的下标+1

解释不清了, 看代码吧

 

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 2e5+10;

LL a[N];
int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        int n;
        scanf("%d", &n);
        
        LL sign = 1, num = 0;
        LL res = 0, minn = -99, resmin = 1, res0 = 1;
        LL resl=n+1, resr = n;
        for(int i = 1; i <= n; i ++)
        {
            scanf("%lld", &a[i]);
            
            //以下四行相当于*a[i], sign表示正负, num表示绝对值=2的个数
            if(a[i] == -2) num ++, sign = -1*sign;
            else if(a[i]==2) num++;
            else if(a[i]==-1) sign = -1*sign;
            else if(a[i]==0) num=0;
            
//从头到尾相乘: (数字为0, 下标为res0 - 1) ~ i
if(sign>0 && num*sign > res) { res = num*sign; //res 正负表示正负, 大小表示多少个2相乘 resl = res0; //resl:结果左边界 resr = i;//resr:结果右边界 } //中间一段相乘 if(sign<0 && minn!=-99 && minn-num*sign > res) { res = minn-num*sign; resl = resmin; resr = i; }
      //以下是后面特例的初始化
if(a[i]==0) { res0 = i+1;//前面最近所在0的下标+1 sign=1; minn = -99;//绝对值最小的负数的大小 resmin = i+1;//绝对值最小的负数的下标后一位 } if(sign<0 && num*sign > minn) minn = num*sign, resmin = i+1; } cout << resl-1 << ' '<< n-resr<<'\n'; } return 0; }

 

posted @ 2022-04-03 20:54  la-la-wanf  阅读(50)  评论(0编辑  收藏  举报