• 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;
                }
            }
        }
    }
  • 相关阅读:
    在CentOS 8 上 部署 .Net Core 应用程序
    Asp.Net Core 查漏补缺《一》 —— IStartFilter
    接口相关数据日志打印
    退款
    识别身份证
    生成二维码
    打造一款简单易用功能全面的图片上传组件
    Redis过期策略+缓存淘汰策略
    Redis主从复制
    .net 平台常用框架
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9667797.html
Copyright © 2020-2023  润新知