Codeforces Round #510 #C Array Product

http://codeforces.com/contest/1042/problem/C

给你一个有n个元素序列,有两个操作:
1,选取a[i]和a[j],删除a[i],将$a[i]*a[j]$赋值给a[j]
2,任意选定一个数删除(只能做一次).
打印操作,让最后剩下的数最大。

题意还是比较好理解的。

我们可以想到我们需要先把所有的0,合为一个,然后判断负数两两配对是否多出一个(!%2),两两配对后,两个负数相乘变为正数,正数当然越乘越大。

如果多出一个来,因为要让乘积最大,那么对于负数而言,我们需要删掉最大的负数,将这个最大的负数和0进行1操作,然后删除0(删除两个数的乘积)。

如果负数为偶数,那么我们直接把0的位置,删掉就好了,将剩下的的乘起来。

这样大体的思想就出来了,要注意一大堆细节问题:

1.如果全是0,那么我们只进行1操作(n-1)次就好,做完return 0;

2.没有0,。

3.没有负数。

4.没有正数。

上边的四种情况在代码中都有体现:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int cnt,cnt1,cnt2,n,x;
struct ahah
{
    int x,pos;
} a[200006],b[200006],c[200006];
bool cmp(ahah a,ahah b){ return abs(a.x)<abs(b.x); }
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&x);
        if(x==0)c[++cnt].pos=i;
        if(x<0)a[++cnt1].x=x,a[cnt1].pos=i;
        if(x>0)b[++cnt2].x=x,b[cnt2].pos=i;
    }
    sort(a+1,a+1+cnt1,cmp);
    sort(b+1,b+1+cnt2,cmp);
    int v=-1;
    if(cnt!=0)
    {
        v=c[1].pos;
        for(int i=2; i<=cnt; i++)
        {
            printf("1 %d %d
",v,c[i].pos);
            v=c[i].pos;
        }
    }
    if(cnt==n)return 0;
    if(cnt1%2==0)
    {
        if(v!=-1)printf("2 %d
",v),v=-1;
        if(cnt1!=0)
        {
            if(v==-1)v=a[1].pos;
            else printf("1 %d %d
",v,a[1].pos),v=a[1].pos;
            for(int i=2; i<=cnt1; i++)
            {
                printf("1 %d %d
",v,a[i].pos);
                v=a[i].pos;
            }
        }
        if(cnt2!=0)
        {
            if(v==-1)v=b[1].pos;
            else printf("1 %d %d
",v,b[1].pos),v=b[1].pos;
            for(int i=2; i<=cnt2; i++)
            {
                printf("1 %d %d
",v,b[i].pos);
                v=b[i].pos;
            }
        }
    }
    else
    {
        if(v==-1)v=a[1].pos;
        else printf("1 %d %d
",v,a[1].pos),v=a[1].pos;
        if(cnt+1!=n)printf("2 %d
",v),v=-1;
        else return 0;
        if(cnt1>1)
        {
            v=a[2].pos;
            for(int i=3; i<=cnt1; i++)
            {
                printf("1 %d %d
",v,a[i].pos);
                v=a[i].pos;
            }
        }
        if(cnt2>0)
        {
            if(v==-1)v=b[1].pos;
            else printf("1 %d %d
",v,b[1].pos),v=b[1].pos;
            for(int i=2; i<=cnt2; i++)
            {
                printf("1 %d %d
",v,b[i].pos);
                v=b[i].pos;
            }
        }
    }
}
原文地址:https://www.cnblogs.com/rmy020718/p/9667797.html